Initially, it was possible from the WSUS console to find out the Windows version of managed computers, but since Windows 10 this no longer works as well. Or rather, it doesn't work at all.
So I've been working on a PowerShell script to get the exact version of computers in a domain.
The aim of this article is to extract a list of computers with their Windows versions into a csv file.
Update: I first found a solution based on WinRM, but finally opted for an even simpler solution that uses the Get-ADComputer command. I'm leaving the WinRM option as it can be used for other purposes.PS C:\ > Get-ADComputer -Filter '*' -Property * | Select-Object Name,OperatingSystem,OperatingSystemVersion | Export-Csv -Path C:\OS_Version_List.csv
PS C:\ > Get-ADComputer -Filter {(Enabled -eq $True)} -Property * | Select-Object Name,OperatingSystem,OperatingSystemVersion -Wrap -Autosize
PS C:\ > Get-ADComputer -Filter 'Name -Like "PC0*" -and Enabled -eq $True' -Property * | Where-Object { $_.OperatingSystem -like "Windows 7*" } | Select-Object Name,OperatingSystem,OperatingSystemVersion -Wrap -Autosize
PS C:\ > Get-ADComputer -Filter {(Enabled -eq $True) -and (Name -Like "PC0*")} -Properties * | where { ($(Get-Date)-[DateTime]::FromFileTime($_.LastLogonTimeStamp)).Days -lt 120 } | Select-object Name,OperatingSystem,OperatingSystemVersion
Here, I'll be using Windows Remote Management, so we need to enable it on every computer we want to retrieve the OS version, for which we can do so via GPO.
WinRM uses TCP ports 5985 (HTTP) or 5986 (HTTPS), so these ports must be open on the target firewall.
Normally, in an Active Directory environment, unencrypted connections (5985 (HTTP)) are disabled. You can check this with the following command:
PS C:\ > winrm get winrm/config/service
PS C:\ > (Get-Service WinRM).Status
PS C:\ > Invoke-Command -ScriptBlock { [System.Environment]::OSVersion.Version } -ComputerName PC01 | Select-Object PSComputerName,Build
I've written a little script that tests wether the computers (from PC0001 to PC0400) are reachable, if so it tries to retrieve the operating system version via WinRM and writes the information to a C:\OS_Version_List.csv file.
#Test for PC0001 to PC0400
1..400 | foreach {
$i="{0:D4}" -f $_
$ping = ping -n 1 "PC$i"| findstr "TTL"
if ($LASTEXITCODE -eq "0")
{
$ip = $PING -replace ".* ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*",'$1'
Write-Host "PC$i is up"
Try { Invoke-Command -ScriptBlock { [System.Environment]::OSVersion.Version } -ComputerName "PC$i" -ErrorAction Stop | Select-Object PSComputerName,Build,@{Name="IP";Expression={"$ip"}} | Export-Csv -Path C:\OS_Version_List.csv -Append }
Catch { '' | Select-Object @{Name="PSComputerName"; Expression={"PC$i"}},@{Name="Build"; Expression={"UNKNOWN"}},@{Name="IP";Expression={"$ip"}} | Export-Csv -Path C:\OS_Version_List.csv -Append }
} else {
Write-Host "PC$i is not available"
}
}
Contact :