With the release of PowerShell 4.0, it is possible you might end up with a mix of systems in your environment. I know I do because I do a lot of writing, testing and development that requires multiple versions in my test network. Recently I was doing some Group Policy work when I thought about WMI filters. A WMI filter is a way to limit Group Policy to machines that meet certain criteria. I thought it would be useful to have a WMI filter that could determine if the computer was running PowerShell 3 or 4. Why? Well one reason would be so that v4 machines would update help from a local v4 source and likewise for v3. So I started looking a developing a WMI query.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
That led to the development of this:
Function Get-WMIPowerShell { [cmdletbinding()] Param( [Parameter(Position=0,ValueFromPipeline=$True)] [alias("cn","pscomputername")] [string[]]$Computername = $env:COMPUTERNAME ) Begin { Write-Verbose -Message "Starting $($MyInvocation.Mycommand)" $wmiParam=@{ class = 'CIM_datafile' filter= ""name='c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe'" ComputerName= $Null ErrorAction= "Stop" } } #begin Process { foreach ($computer in $computername) { Write-Verbose "Querying $computer.toUpper())" $wmiParam.Computername=$Computer Try { Get-WMIObject @wmiParam | Select @{name="Computername";Expression={$_.CSName}}, Name,Version,FileSize, @{Name="Installed";Expression={$_.ConvertToDateTime($_.InstallDate)}} } Catch { Write-Warning "Failed to retrieve WMI information from $computername" Write-Warning $_.Exception.Message } } #foreach } #process End { Write-Verbose -Message "Ending $($MyInvocation.Mycommand)" } #end } #end function
This function uses WMI to retrieve the instance of the CIM_DATAFILE class for PowerShell.exe. I have found when querying for this class to be as specific in your query as you can. This runs pretty quickly and returns some useful information. I can even run it for a group of computers.
PS S:\> Get-WMIPowerShell -comp chi-dc01,chi-dc02,chi-dc04,chi-hvr2.globomantics.local,jdhit-dc01,novo8 | out-gridview -title "PS Version"
The first two machines are running PowerShell 2.0, the next 2 v3 and the last 2 v4. Now that I know this works, I can create a WMI filter with a query like this:
"Select * from CIM_Datafile where name='c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe' AND version like '6.2%'"
This should filter only for computers running PowerShell 3.0.
I wrote this function thinking I would add support for alternate credentials. But if you don't need it, you can also get the same information using the [WMI] type accelerator.
PS S:\> [WMI]"\\CHI-DC04\root\cimv2:CIM_DataFile.Name='c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe'" Compressed : False Encrypted : False Size : Hidden : False Name : c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe Readable : True System : False Version : 6.2.9200.16384 Writeable : True
I needed to test and develop a SELECT query which is why I ended up with the function I did. The date information is extra and if you use Get-CIMInstance, the dates are converted for you.
$wmiParam=@{ class = 'CIM_datafile' filter= "name='c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe' AND version like '6.2%'" ComputerName= 'CHI-DC04' ErrorAction= "Stop" } Get-CIMInstance @wmiParam | Select PSComputername,Name,Version,FileSize,InstallDate
Yes, I know you can get this information with Test-WSMan as well and that is certainly a much easier way. Although if by chance you still have PowerShell 1.0 in use, I don't think that will work. Anyway, there you have it. A quick way using WMI to find out the PowerShell version and a query you can use to build a WMI filter for Group Policy.
Enjoy.
UPDATE 11/14
I don't know what I was thinking with my original query. It was much more complicated than it needed to be. I've updated my code samples with a better filter. Remember when using \ in any paths, it needs to be escaped which is why you see the name as you do.