[CmdletBinding()] param ( [Parameter(Mandatory=$true)][string[]]$Computer ) $OutputDir = $PSScriptRoot $ScriptName = [IO.Path]::GetFileNameWithoutExtension($PSCommandPath) $OutputFile = "\\Server\Share\DeviceHealthInfo.csv" function Get-DateTime { return (Get-Date -Format "dd/MM/yyyy HH:mm:ss") } function Get-WindowsUpdateTitle { Param ( [Parameter(Mandatory=$true)][string]$Article ) $WebResponse = Invoke-WebRequest "https://www.catalog.update.microsoft.com/Search.aspx?q=$Article" $table = $WebResponse.ParsedHtml.body.getElementsByTagName("table") | Where {$_.className -match "resultsBorder"} $rows = $table.rows | Where {$_.id -ne "headerRow"} $updateTitle = (($rows.cells | Where {(($_.cellIndex -eq 1 -and $_.innerText -match "$osName", "for x$osArch-based Systems") -and ($_.innerText -notmatch "Dynamic"))} | Select -ExpandProperty innerText).TrimEnd()) -join " / " return $updateTitle } if ($Computer -match "[\\\.]+") { if (-Not (Test-Path -Path $Computer)) { Write-Output ("{0}: {1}" -f $(Get-DateTime), "You have specified an invalid file for Computer list. Please check and try again") break } $Computer = Get-Content -Path $Computer } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $Computer | ForEach-Object { $hostname = $_ $status = "" $statusMessage = "" $systemDrive = "" $ipAddress = "" $osName = "" $osArch = "" $osDisk = "" $lastBoot = "" $osDiskSizeG = "" $osDiskFreeG = "" $osDiskFreeP = "" $update = "" $updateKB = "" $updateInstallDate = "" $updateTitle = "" if (Test-Connection -ComputerName $_ -BufferSize 16 -Count 2 -Quiet) { $status = "Online" Invoke-Command -ComputerName $hostname -ErrorAction Stop -ScriptBlock {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12} try { $statusMessage = "Computer is online" $systemDrive = Invoke-Command -ComputerName $hostname -ErrorAction Stop -ScriptBlock {[Environment]::GetEnvironmentVariable(“SystemDrive”)} $ipAddress = ([System.Net.Dns]::GetHostAddresses($hostname)) -join ", " $osName = (Get-WmiObject -ComputerName $hostname -ClassName Win32_OperatingSystem).Caption | Select @{n="OSName";e={([regex]"(\bWindows\b\s+[a-zA-Z0-9]+(?:\s+[0-9]{4})?(?:\s+R[0-9]{1})?)").Match($_).Groups[1].Value}} | Select -ExpandProperty OSName $osArch = (Get-WmiObject -ComputerName $hostname -ClassName Win32_Processor).AddressWidth | Select -First 1 #$osArch = [regex]::match(((Get-WmiObject -ComputerName $hostname -ClassName Win32_OperatingSystem).OSArchitecture), "^([0-9]{2})").Groups[1].Value $osDisk = Get-CimInstance -ComputerName $hostname -ClassName Win32_LogicalDisk | Where {($_.DeviceID -eq $systemDrive)} | Select Size, FreeSpace $lastBoot = (Get-Date(Get-CimInstance -ComputerName $hostname -ClassName Win32_OperatingSystem | Select -ExpandProperty LastBootupTime)) $osDiskSizeG = [math]::Round(($osDisk.Size / 1GB), 2) $osDiskFreeG = [math]::Round(($osDisk.FreeSpace / 1GB), 2) $osDiskFreeP = [math]::Round(($osDisk.FreeSpace / $osDisk.Size * 100), 2) $session = [activator]::CreateInstance([type]::GetTypeFromProgID("Microsoft.Update.Session", $hostname)) $searcher = $session.CreateUpdateSearcher() $historyCount = $searcher.GetTotalHistoryCount() $update = $searcher.QueryHistory(0, $historyCount) | Where {(($_.Title -like "*Cumulative Update for Windows*") -or ($_.Title -like "*Security Monthly Quality Rollup for Windows*") -or ($_.Title -like "*Security Only Quality Update for Windows*") -or ($_.Title -like "*Security Update for Windows*")) -and $_.Operation -eq 1} | Sort @{e={[int][regex]::match(($_.Title), "\(KB(.*?)\)").Groups[1].Value}} -Descending | Select -First 1 @{n='Article';e={[string][regex]::match(($_.Title), "\(KB(.*?)\)").Groups[1].Value}}, Title, @{n='InstalledOn';e={$_.Date}} $updateKB = $update.Article $updateInstallDate = (Get-Date($update.InstalledOn)) $updateTitle = Get-WindowsUpdateTitle($update.Article) } catch { $status = "Error" $statusMessage = $_ } } else { $status = "Offline" $statusMessage = "Computer is offline" } $details = New-Object PSObject -Property @{ "Hostname" = $hostname "Status" = $status "Status Message" = $statusMessage "IP Address" = $ipAddress "Last Boot Date" = $lastBoot "OS Disk Size GB" = $osDiskSizeG "OS Disk Free GB" = $osDiskFreeG "OS Disk Free %" = $osDiskFreeP "Update KB" = $updateKB "Update Title" = $updateTitle "Update Install Date" = $updateInstallDate "Scan Date" = (Get-Date) } $details | Select "Hostname", "Status", "Status Message", "IP Address", "Last Boot Date", "OS Disk Size GB", "OS Disk Free GB", "OS Disk Free %", "Update KB", "Update Title", "Update Install Date", "Scan Date" | Export-CSV $OutputFile -Append -NoTypeInformation }