AppActivate does not allow to search by word - windows

I have an application on my Windows that the window name is something like this: a random number followed by space and after that comes the name of it RECFED. For example "3894 RECFED".
I would like to send a key to that window but I can do that with AppActivate cause I can't know the exactly title of the window. I am using something like this
$wshell = New-Object -ComObject WScript.Shell
$wshell.AppActivate("RECFED")
$wshell.SendKeys('a')
The code above works if I place the exact name of the window at AppActivate but I don't have the exact name in hand all the time.

Use Get-Process to identify a process by its window title, then use that process's PID for bringing the window to the foreground:
$id = Get-Process |
Where-Object { $_.MainWindowTitle -like '*RECFED*' } |
Select-Object -First 1 -Expand Id
$wshell.AppActivate($id)
With that said, be warned that SendKeys() is a terrible (flaky, unreliable) automation approach, that should only be used as an absolute last resort when everything else has failed.

Related

Search membership queries in SCCM

More details on what we require:
We have a bunch of AD groups that may not be doing anything at all. What we would ideally like to do is somehow search SCCM for any usage of a particular AD group. Like if the group is used as part of a membership query anywhere.
For example I have tried the following in SCCM Powershell to look for any usage of the AD group sccm.minitablets :
Get-CMUserCollectionQueryMembershipRule | Where -Property RuleName -Like "%mini%"
I don't think the above command is of much use, as it has a required parameter that takes a specific collection name, whereas I need to search for any use of sccm.minitablets in any collection or any membership rule query across the board.
Is this even possible?
Was able to find a solution to this, for anyone else who might be interested:
Get-CMUserCollection | Get-CMUserCollectionQueryMembershipRule | Where -Property QueryExpression -Like "*mini*"
Get-CMDeviceCollection | Get-CMDeviceCollectionQueryMembershipRule | Where -Property QueryExpression -Like "*mini*"

Windows PowerShell Command To List Group Members - Fine-Tuning

I've crafted the command below which listed out the members of a group:
gwmi win32_group -filter 'Name="Administrators"'|%{$_.GetRelated('Win32_UserAccount')} | select Name
The command above works, however, it takes ages to complete, is there a way of fine-tuning the command above so it runs faster?
Please note, I am limited to PowerShell 2.0.
Edit:
Seems like the command above is also querying all DC accounts. How do I only query local users?
Tuning
The slow part in your pipeline is the call of .GetRelated(), because this will evaluate the associations of WMI class instances, which may be huge lists. So you have to be careful and filter as much as possible. You can do it like this:
(Get-WmiObject -Class Win32_Group -Filter "LocalAccount = TRUE and SID = 'S-1-5-32-544'").GetRelated("Win32_Account", "Win32_GroupUser", "", "", "PartComponent", "GroupComponent", $false, $null) | Select-Object -Property Name
Note, that I used the well-known SID of the Administrators group to look for it, because its name may differ in other languages. I also queried for Win32_Account instead of Win32_UserAccount to really return ALL members of the Administrators group which may include other groups and not only user accounts. You may change this according to your needs of course. You can read more about this tuning in this article.
Different approaches
Another approach would be to define everything in one WMI query:
Get-WmiObject -Query "ASSOCIATORS OF {Win32_Group.Domain='$env:COMPUTERNAME',Name='Administrators'} WHERE AssocClass=Win32_GroupUser ResultRole=PartComponent" | Select-Object -Property Name
Further more, you can use the net tool to query the members of the Administrators group:
net localgroup Administrators
Drawback: You have to parse the textual output.

Finding users with "edit" and "delete" rights for Exchange Distribution Groups

Is it possible to create a script that will find all the exchange distribution groups with a certain prefix (say "X_"), and find the users that can "edit" and "delete" this group?
I've managed to use the exchange console shell to return all the groups that start with "X_" with this script (look under this paragraph), and return who is listed as "managed by". But I still need to find the users that can "edit" and "delete" the group..
Get-DistributionGroup -Identity "X_*" |
Format-Table Name, ManagedBy -Auto |
Export-Csv -path "C:\Temp\Distribution Groups\New folder\Distribution Groups.csv" -Encoding ascii -NoTypeInformation

Powershell - filtering output of command

I'm quite new to powershell, but I've done a lot of batch scripting (yay for moving into the 'now!'). I'm trying to re-write my largest accomplishment in batch scripting into powershell, and right off the bat I'm hitting a bit of a wall.
What my original batch script did was install drivers for all of the detected system hardware. It did this by running devcon.exe and doing a search on the output, looking for VEN_ &DEV_ and trying to match it up with a comparison. This took a bit of time on slower computers (i3/Atom/slow AMD).
I stumbled across this command in powershell:
get-wmiobject -class CIM_VideoController PNPDeviceID
It spits out a list which contains just a few bits of info on the display adapter. The line in particular I'd like is the PNPDeviceID. I so far haven't had much luck in finding a way to manupulate the output to list just the VEN_ numbers.
Here's what I'd like to do: Run the command above, manipulate it so I get just the vendor number into one variable and the device number into another variable.
I tried doing this:
get-wmiobject -class CIM_VideoController PNPDeviceID | Select-String -Pattern "PNPDeviceID" -SimpleMatch
The problem I'm having is, it spits out nothing at all. I also have no clue on how to manipulate the output of that line further giving me only the 4 digit identifier of the 'VEN_' or the 'DEV_'.
Would anyone know how to do this?
I mean no disrespect, but this is pretty basic stuff. Have you considered finding a book (even an online one) and reading up on PowerShell? I've heard good things about Learning PowerShell In A Month Of Lunches.
As for your request, to get the four digit ID you could pipe that property's value to a regex match, and then output that match. It could be done like this:
$VidCardID = get-wmiobject -class CIM_VideoController PNPDeviceID | Where{$_.PNPDeviceID -match "VEN_(\d{4})"} | ForEach{$Matches[1]}
That will set $VidCardID to the 4 digit ID for the video card.
You can just do this:
$deviceID = (get-wmiobject -class CIM_VideoController).PNPDeviceID
the output of such objects are allways stored in a property which you can access by dot notation

IE Automation with Powershell

I am attempting to automate the login to website on our intranet using Powershell and IE. So far, I have the following code that works:
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("https://somepage/jsp/module/Login.jsp/")
while($ie.ReadyState -ne 4) {start-sleep 1}
$ie.visible = $true
$doc = $ie.Document
If ($doc.nameProp -eq "Certificate Error: Navigation Blocked") {
$doc.getElementByID("overridelink").Click()
}
$loginid = $doc.getElementById("loginid")
$loginid.value= "username"
$password = $doc.getElementById("password")
$password.value = 'somepass'
$ie.navigate("javascript:doSubmit('login')",$null,$true)
So, the problem area I have now is that the site closes the original window used to login and opens a new IE window. How do I go about submitting inputs to that new window? I know I can use something like tasklist.exe /v to get the PID of the new window... but I'm not sure how I would go about taking control of it.
Also, after viewing my code, please know I do not intend to use embedded user name and passwords. That's only in place so that I don't have to continually type a un/pw combo every time I want to test the script.
After trying a bit more...
$applist = new-object -com shell.application
$newie = $applist.windows() | where {$_.Type -eq "HTML Document" -and $_.LocationURL -match "MainFrame.jsp"}
I found an old article that describes how to do what you're looking for, by looping through the windows of a Shell.Application object. I have to say that while it looks possible and does seem to answer your direct question, the approach seems pretty unpleasant and fragile to me.
If you're not averse to trying a different approach, I would suggest giving Selenium Webdriver a shot. You can use the Internet Explorer driver, and the C# examples in the documentation generally translate nicely into PowerShell. You get some other nice benefits too, like drivers for other web browsers or the ability to wait for a condition instead of relying on sleep/check loops. You will also have a driver.switchTo() function that allows you to bounce between windows or frames.
Try this.
$shell = (New-Object -ComObject Shell.Application).Windows()
$shell.Count
7
you have items 0-6 you can check this way.
$shell.Item(0).LocationName
or
$shell.Item(0).LocationURL
$shell.Item(1).LocationName
$shell.Item(1).LocationURL

Resources