Powershell - filtering output of command - windows

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

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.

AppActivate does not allow to search by word

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.

Powershell Auditing effective windows share permissions and outputting to CSV

Powershell noob here. I'm trying to create a script that will take a list of users, a list of network shares, enumerate effective permissions for the user/share and output to CSV for audit purposes.
I've had success using GetPACEffectiveAccess from the PowerShellAccessControl Module on Technet gallery to do the enumeration, but am getting completely stuck on how to output this data to CSV how I want it.
The code I have is pretty simple:
$users=gc C:\scripts\users.txt
$shares=gc C:\scripts\shares.txt
foreach ($user in $users) {
foreach ($share in $shares) {
Get-PACEffectiveAccess -Path $share -Principal $user | select-object principal, accessmask, path | Export-Csv C:\scripts\EffectivePermissions\Audit.csv -append -NoTypeInformation}}
Since I have no idea how to do tables on StackOverflow (wow I am bad at this) I have attached a screenshot of the output I am getting from my simple script, and then the output I would like to get.
Any help would be much appreciated!
Thanks
After you gather the data, instead of outputting straight to the csv, you could add it to a two dimensional array, format it the way you'd like, and outfile it to a csv.

Change Chrome Settings via Powershell

I want to make a script to change the default page zoom in Chrome, however I do not know where these options are stored.
I guess that I have to find an appropriate options text file, parse it, and then make a textual replacement there, using powershell in order to apply the changes.
I need to do it every time I plugin my laptop to an external monitor, and it is kinda annowying to do it by hand
Any ideas?
The default zoom level is stored in a huge JSON config file called Preferences, that can be found in the local appdata folder:
$LocalAppData = [Environment]::GetFolderPath( [Environment+SpecialFolder]::LocalApplicationData )
$ChromeDefaults = Join-Path $LocalAppData "Google\Chrome\User Data\default"
$ChromePrefFile = Join-Path $ChromeDefaults "Preferences"
$Settings = Get-Content $ChromePrefFile | ConvertFrom-Json
The default Page Zoom level is stored under the partition object, although it seems to store it as a unique identifier with some sort of ratio value, this is what it looks like with 100% zoom:
PS C:\> $Settings.partition.default_zoom_level | Format-List
2166136261 : 0.0
Other than that, I have no idea. I don't expect this to be a good idea, Chrome seems to update a number of binary values everytime the default files are updated, you might end up with a corrupt Preferences file
$Env:
Is a special PSdrive that contains many of the SpecialFolder Paths
$Env:LOCALAPPDATA
and
[Environment]::GetFolderPath( [Environment+SpecialFolder]::LocalApplicationData )
Yield the same result in addition to the rest of Mathias answer.

Resources