Trigger a remote GPUpdate without PSRemoting or PSExec

I recently enabled Windows Firewall on an unused server via GPO, but forgot to include the inbound RDP exception. This, of course, kicked me off my RDP session.

Rather than wait ~90 minutes for my revised GPO to take effect, I found that I could trigger a GPUpdate remotely using WMI (WinRM wasn’t enabled, and I didn’t want to use PSExec)

The following command does the trick:

Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "gpupdate.exe" -ComputerName <computername>

PowerShell/WMI: An alternative to using Win32_Product

Today I wanted to find the MSI uninstall string for a specific install of Adobe Reader on a remote computer. Seeing as using Win32_Product in WMI queries to look for installed software is not a good idea, and even Microsoft warn against using it, I needed to find an alternative.

This one is fairly long-winded, but it gets the job done. It will search both the 32-bit and 64-bit Uninstall keys in the registry.

"","Wow6432Node" | ForEach-Object {Get-ChildItem HKLM:\SOFTWARE\$_\Microsoft\Windows\CurrentVersion\Uninstall\ | ? {($_.GetValue("DisplayName")) -like "*Adobe*"}}

If you have any suggestions or alternatives, please feel free to post them in the comments.

PowerShell helper function to return readable storage sizes

I came across this code whilst looking through the built-in cmdlets that come with Windows 8.x. The function was located in storage.format.ps1xml and is used to format disk capacities in list and table views, so all credit goes to Microsoft for this one.

I’ve since appropriated it as a helper function in another WMI/CIM-related script, as it’s quite handy for converting the raw byte values that Get-CimInstance returns.

function ReadableStorage ($size) {
    $postfixes = @( "B", "KB", "MB", "GB", "TB", "PB" )
    for ($i=0; $size -ge 1024 -and $i -lt $postfixes.Length - 1; $i++) { $size = $size / 1024; }
    return "" + [System.Math]::Round($size,2) + " " + $postfixes[$i];
}

Here are some examples of it in action:

PS C:> ReadableStorage(1024)
1 KB

PS C:> ReadableStorage(2147483648)
2 GB

PS C:> ReadableStorage(12384898975268864)
11 PB

Apply GPO based on installed Server Feature (WMI Filtering)

Today I came across a server that had been placed in a sub-OU by a colleague simply for the purposes of applying a GPO to it. The GPO in question was configured to make some changes to the BranchCache feature.

If the policy needs to apply to a subset of all servers in an OU, it would be cleaner to apply a WMI filter to the GPO itself rather than limiting the scope of the GPO by explicit security filtering.

Here’s what I did to clean it up:

  1. Created a WMI filter in GPMC:
    SELECT * FROM Win32_ServerFeature WHERE Name like ‘branchcache%’
  2. Applied the filter to the GPO in question
  3. Applied the GPO to the OU where the server originally lived
  4. Moved the server back to the original OU

This same strategy could be used to apply a policy to all IIS servers, all file servers, etc. The possibilities are practically limitless.

You could even filter on something like Win32_Product to apply a specific GPO to Exchange servers, for example.

SELECT * FROM Win32_Product WHERE name = 'microsoft exchange server'

Don’t use Win32_Product. It’s not a good idea, and even Microsoft warn against using it.