functions/Get-WindowsVersion.ps1
|
<# Modified 9/29/2020 so that Invoke-Command doesn't attempt to create a remoting session to the local machine. #Issue 90 #> function Get-WindowsVersion { [cmdletbinding()] [OutputType('WindowsVersion')] [alias('wver')] param ( [Parameter( Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [string[]]$Computername = $env:COMPUTERNAME, [ValidateNotNullOrEmpty()] [PSCredential]$Credential, [switch]$UseSSL, [Int32]$ThrottleLimit, [ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')] [ValidateNotNullOrEmpty()] [string]$Authentication = 'default' ) begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" $sb = { $RegPath = 'HKLM:\SOFTWARE\Microsoft\Windows nt\CurrentVersion\' <# 9/15/2022 JDH Revised to use `systeminfo to retrieve the operating system name and if that fails, fall back to using the registry entry. The registry entry for Windows 11 typically still shows Windows 10. #> $regData = Get-ItemProperty -Path $RegPath <# 30 May 2024 It appears that SystemInfo is localized so I can't assume "OS Name" will always be the property name. I am trusting the output order will always be the same. Issue #142 #> $tmpCsv = [system.io.path]::GetTempFileName() Start-Process systeminfo -ArgumentList '/fo csv' -Wait -WindowStyle Hidden -RedirectStandardOutput $tmpCSV if ((Get-Item $tmpCSV).Length -gt 0) { #$OSName = Import-CSV $tmpCsv | Select-Object -expand "OS Name" $in = Import-Csv $tmpCsv #getting properties from the PSObject $OSName = $in.PSObject.Properties | Select-Object -Skip 1 -First 1 -ExpandProperty Value Remove-Item -Path $tmpCsv } else { $OSName = $regData.ProductName } $regData | Select-Object -Property @{Name = 'ProductName'; Expression = { $OSName } }, EditionID, ReleaseID, BuildBranch, @{Name = 'Build'; Expression = { "$($_.CurrentBuild).$($_.UBR)" } }, DisplayVersion, @{Name = 'InstalledUTC'; Expression = { ([datetime]'1/1/1601').AddTicks($_.InstallTime) } }, @{Name = 'Computername'; Expression = { $env:computername } } } #close scriptblock #update PSBoundParameters so it can be splatted to Invoke-Command [void]$PSBoundParameters.Add('ScriptBlock', $sb) } #begin process { if (Test-IsPSWindows) { if ($Computername -eq $ENV:Computername) { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing the local host" #remove all any passed parameters 'Credential', 'UseSSL', 'ThrottleLimit', 'Authentication' | ForEach-Object { if ($PSBoundParameters.ContainsKey($_)) { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Removing parameter $_" [void]($PSBoundParameters.Remove($_)) } } } else { [void]$PSBoundParameters.add('HideComputername', $True) } Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Invoking command" $PSBoundParameters | Out-String | Write-Verbose $results = Invoke-Command @PSBoundParameters | Select-Object -Property * -ExcludeProperty RunspaceID, PS* if ($Results) { foreach ($item in $results) { [PSCustomObject]@{ PSTypeName = 'WindowsVersion' ProductName = $item.ProductName ReleaseVersion = $item.DisplayVersion EditionID = $item.EditionID ReleaseID = $item.ReleaseID Build = $item.Build Branch = $item.BuildBranch InstalledUTC = $item.InstalledUTC Computername = $item.Computername } } } } else { Write-Warning 'This command requires a Windows platform' } } #process end { Write-Verbose "[$((Get-Date).TimeOfDay)END ] Ending $($MyInvocation.MyCommand)" } #end } #close function function Get-WindowsVersionString { [cmdletbinding()] [OutputType('System.String')] param ( [Parameter( Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [string[]]$Computername = $env:COMPUTERNAME, [PSCredential]$Credential, [switch]$UseSSL, [Int32]$ThrottleLimit, [ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')] [ValidateNotNullOrEmpty()] [string]$Authentication = 'default', [Parameter(HelpMessage = "Display an ANSI styled string.")] [switch]$UseStyle ) begin { Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" $styleHash = @{ CN = "$([char]27)[93m" Version = "$([char]27)[92;3m" Build = "$([char]27)[96m" Reset = "$([char]27)[0m" } If ($PSBoundParameters.ContainsKey('UseStyle')) { [void]($PSBoundParameters.Remove('UseStyle')) } } #begin process { Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Calling Get-WindowsVersion" $results = Get-WindowsVersion @PSBoundParameters #write a version string for each computer ` foreach ($result in $results) { if ($UseStyle) { '{4}{3}{7} {5}{0} Version {1}{7} {6}(OS Build {2}){7}' -f $result.ProductName, $result.EditionID, $result.build, $result.computername,$styleHash.CN,$styleHash.Version,$styleHash.Build,$styleHash.Reset } else { '{3} {0} Version {1} (OS Build {2})' -f $result.ProductName, $result.EditionID, $result.build, $result.computername } } } #process end { Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" } #end } |