Get-WindowsVersion.psm1

function Get-WindowsVersion {
    <#
.SYNOPSIS
    List current or History Windows Version from local or remote computer. List with Active Directory SearchBase.
.DESCRIPTION
    List current or History Windows Version from local or remote computer. List with Active Directory SearchBase.
.PARAMETER ComputerName
    Name of server to list Windows Version from remote computer.
.PARAMETER ADSearchBase
    Active Directory SearchBase of server to list Windows Version from remote computer.
.PARAMETER History
    List History Windows Version from computer.
.EXAMPLE
    Get-WindowsVersion
    List Windows Version on local computer.
.EXAMPLE
    Get-WindowsVersion -ComputerName pc1, pc2
    List Windows Version on multiple remote computer.
.EXAMPLE
    Get-WindowsVersion -ADSearchBase "OU=Computers,DC=comodo,DC=com".
    List Windows Version on Active Directory SearchBase computer.
.EXAMPLE
    Get-WindowsVersion -History.
    List History Windows Version on local computer.
.EXAMPLE
    Get-WindowsVersion -ComputerName pc1, pc2 -History
    List History Windows Version on multiple remote computer.
#>

    [CmdletBinding(DefaultParameterSetName = "Par1")]
    param (
        [parameter(Position = 0, ParameterSetName = "Par1")] [string[]] $ComputerName = "localhost",
        [parameter(ParameterSetName = "Par2")] [string] $ADSearchBase,
        [parameter(ParameterSetName = "Par1")] [parameter(ParameterSetName = "Par2")] [switch] $History
    )
    if ($PsVersionTable.OS -match "Windows") {
        if ($ADSearchBase) {
            try {
                $ADSearch = New-Object System.DirectoryServices.DirectorySearcher
                $ADSearch.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ADSearchBase")
                $ADSearch.Filter = "(&(objectClass=computer)(objectCategory=computer)(!useraccountcontrol:1.2.840.113556.1.4.803:=2))"
                $ADSearchFind = $ADSearch.FindAll()
            }
            catch { Write-Warning "ADSearchBase not found" }
            $ComputerName = $ADSearchFind | ForEach-Object -Parallel { $_.Properties.name } | Sort-Object
        }
        if ($ComputerName) {
            $WindowsVersionObject = $ComputerName | ForEach-Object -Parallel {
                $Computer = $_.ToUpper()
                if (($Computer -like "localhost") -or ((Test-Connection -Count 1 -TargetName $Computer).Status -match "Success")) {
                    $WmiClass = [WmiClass]"\\$Computer\root\default:stdRegProv"
                    $HKLM = 2147483650
                    $Reg1 = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
                    $Reg2 = "SYSTEM\Setup\"
                    $Reg3 = ($WmiClass.EnumKey($HKLM, $Reg2)).snames -like "Source*"
                    $Reg4 = foreach ($Reg3Item in $Reg3) { "$Reg2$Reg3Item" }
                    $Reg5 = @()
                    $Reg5 += $Reg1
                    $Reg5 += $Reg4
                    foreach ($Reg in $Reg5) {
                        $Major = $WmiClass.GetDWordValue($HKLM, $Reg, "CurrentMajorVersionNumber").UValue
                        $Minor = $WmiClass.GetDWordValue($HKLM, $Reg, "CurrentMinorVersionNumber").UValue
                        $Build = $WmiClass.GetStringValue($HKLM, $Reg, "CurrentBuildNumber").sValue
                        $UBR = $WmiClass.GetDWordValue($HKLM, $Reg, "UBR").UValue
                        $ReleaseId = $WmiClass.GetStringValue($HKLM, $Reg, "ReleaseId").sValue
                        $ProductName = $WmiClass.GetStringValue($HKLM, $Reg, "ProductName").sValue
                        $ProductId = $WmiClass.GetStringValue($HKLM, $Reg, "ProductId").sValue
                        $InstallTime1 = $WmiClass.GetQWordValue($HKLM, $Reg, "InstallTime").UValue
                        $InstallTime2 = ([datetime]::FromFileTime($InstallTime1))
                        if ($Major.Length -le 0) { $Major = $WmiClass.GetStringValue($HKLM, $Reg, "CurrentVersion").sValue } # Windows 6.x
                        if ($ReleaseId.Length -le 0) { $ReleaseId = $WmiClass.GetStringValue($HKLM, $Reg, "CSDVersion").sValue } # Windows 6.x
                        if ($InstallTime1.Length -le 0) { $InstallTime2 = (Get-CimInstance Win32_OperatingSystem -ComputerName $Computer).InstallDate } # Windows 6.x
                        if (-not($Major.Length -le 0)) { $Major = "$Major." } # Add Points
                        if (-not($Minor.Length -le 0)) { $Minor = "$Minor." } # Add Points
                        if (-not($UBR.Length -le 0)) { $UBR = ".$UBR" } # Add Points
                        if ($Reg -match "Source") { $HistorySource = $true } else { $HistorySource = $false }
                        [PSCustomObject]@{
                            PSTypeName     = "Get-WindowsVersion"
                            ComputerName   = $Computer
                            ProductName    = $ProductName
                            WindowsVersion = $ReleaseId
                            WindowsBuild   = "$Major$Minor$Build$UBR"
                            ProductId      = $ProductId
                            InstallTime    = $InstallTime2
                            History        = $HistorySource
                        }
                    }
                }
            }
            if ($History) { $WindowsVersionObject } else { $WindowsVersionObject | Where-Object { $_.History -eq $false } }
        }
    }
    else {
        Write-Warning "PSVersion OS not Windows"
    }
}
New-Alias -Name gwv -Value Get-WindowsVersion
Export-ModuleMember -Alias * -Function Get-WindowsVersion