Public/Get-ServerStatus.ps1
<#
.SYNOPSIS Get-ServerStatus.ps1 - Test network, RPC, and RDP connections, as well as gathering uptime and pending reboot status against one or more computers. .DESCRIPTION Get-ServerStatus.ps1 - Test an RPC connection (WMI request) against one or more computer(s) with test-connection before to see if the computer is reachable or not first .PARAMETER ComputerList Defines the path to the file containing a list of servers to test against, either by hostname or IP address. .PARAMETER ComputerName Defines the computer name or IP address to test against. Could be an array of server names. .PARAMETER User Username .PARAMETER Pass Password .NOTES File Name : Get-ServerStatus.ps1 Author : Marcus Daniels - danielm1@mskcc.org Adapted From : RPC-Ping.ps1 by Fabrice ZERROUKI - fabricezerrouki@hotmail.com .EXAMPLE PS D:\> Get-ServerStatus.ps1 -ComputerList C:\servers.txt -ExportPath C:\Reports\ Get server status from a list of servers and export to a CSV at the defined path. .EXAMPLE PS D:\> Get-ServerStatus.ps1 -ComputerName SERVER1 Get server status for SERVER1 as current user .EXAMPLE PS D:\> Get-ServerStatus.ps1 -ComputerName SERVER1,192.168.0.23 -Credential JSMith Get server status for SERVER1 and 192.168.0.23 as a supplied user. Can also pass "-Credential (Get-Credential)" for a Windows security prompt. #> function Get-ServerStatus { [CmdletBinding(DefaultParameterSetName='ByComputerList')] Param( [Parameter(Mandatory = $true, ParameterSetName = 'ByComputerList')] [array]$ComputerList, [Parameter(Mandatory = $true, ParameterSetName = 'ByComputerName')] [array] $ComputerName, [Parameter()] [string[]] $User, [Parameter()] $Pass, <# [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, #> [Parameter()] [string] $ExportPath, [Parameter()] [int32] $OptionalPort, [switch] $ErrorLog ) $time = (Get-Date -UFormat %H.%M.%S) $ExtensionCheck = $null if ($ExportPath) { $WriteReport = $true $ExtensionCheck = (Get-Extension -ExportPath $ExportPath) Switch ($ExtensionCheck) { "True" { do { $ExportPath = Read-Host "Invalid path or directory. Filenames are not allowed" $ExtensionCheck = (Get-Extension -ExportPath $ExportPath) } while ($ExtensionCheck -eq "True") } "False" { } } $ReportsDir = $ExportPath } else { $WriteReport = $false $ReportsDir = $ExportPath } if ($WriteReport -eq $true -and $ReportsDir[-1] -eq "\") { $ReportsDir = $ReportsDir.Substring(0,$ExportPath.Length-1) } if ($ErrorLog) { try { Import-Module PSLogging -ErrorAction Stop $LogPath = ".\" $LogName = “ServerStatus_ErrorLog_" + (Get-Date -Format MM.dd.yyyy) + "_$time.log” Start-Log -LogPath $LogPath -LogName $LogName -ScriptVersion “1.0” | Out-Null $Log = $LogPath + $LogName } catch { Write-Host $_ } } if ($WriteReport -eq $true -and (!(Test-Path $ReportsDir)) ) { New-Item -Path $ReportsDir -ItemType Directory | Out-Null } if ($PSCmdlet.ParameterSetName -eq 'ByComputerList') { $ComputerName = (Get-Content $ComputerList) } # Reset the user just in case $RunAsUser = $null # Authentication logic if ($User -and $Pass) { $Pass = ConvertTo-SecureString -String $Pass -AsPlainText -Force $Mycreds = New-Object System.Management.Automation.PSCredential ($User, $Pass) } elseif ($User -ne $null -and $Pass -eq $null) { Write-Host "Prompt" $Pass = Read-Host "Enter Password" -AsSecureString $Mycreds = New-Object System.Management.Automation.PSCredential ($User, $Pass) } #elseif ($User -eq $null -and $Pass -eq $null) { else { $RunAsUser = $True $mycreds = [System.Management.Automation.PSCredential]::Empty } # Create an empty array for our end results # $Results = @() # Set the report filename # $Reportname = "ServerStatusReport_" + (Get-Date -Format MM.dd.yyyy) + "_$time.csv" # Begin main for loop on the computer array ForEach ($Computer in $ComputerName) { # Start progress bar $i++ $progress = [math]::truncate(($i / $computername.length) * 100) Write-Progress -activity "Checking $computer" -status "$Progress percent complete: " -PercentComplete (($i / $computername.length) * 100) # Create an object to hold each machine's results # $Result = New-Object System.Object # Write the hostname to the array # $Result | Add-Member -MemberType NoteProperty -Name "Hostname" -Value $Computer -Verbose # Starting main if/else statement: pass/fail ping test # if (Test-Connection -ComputerName $Computer -Quiet -Count 1) { $Result | Add-Member -MemberType NoteProperty -Name "Ping Result" -Value "Online" # RDP Try/Catch try { $RDPOnline = (Test-Port $Computer -Port 3389 -ErrorAction Stop) Switch ($RDPOnline) { "False" { $Result | Add-Member -MemberType NoteProperty -Name "RDP" -Value "Down" } "True" { $Result | Add-Member -MemberType NoteProperty -Name "RDP" -Value "Up" } } } catch { $Result | Add-Member -MemberType NoteProperty -Name "RDP" -Value "Unknown" } # First an RPC port test $RPCOnline = (Test-Port $Computer -Port 135 -ErrorAction Stop) Switch ($RPCOnline) { "False" { $Result | Add-Member -MemberType NoteProperty -Name "RPC" -Value "Down" } "True" { # RPC Try/Catch via WMI call try { (Get-WmiObject win32_computersystem -ComputerName $Computer -Credential $Mycreds -ErrorAction Stop | Out-Null) $Result | Add-Member -MemberType NoteProperty -Name "RPC" -Value "Online" } catch { $Result | Add-Member -MemberType NoteProperty -Name "RPC" -Value "Error: $_" } # Uptime Try/Catch try { $uptime = (Get-Uptime -ComputerName $Computer -Credential $mycreds) $Result | Add-Member -MemberType NoteProperty -Name "Uptime (DD:HH:MM)" -Value $uptime } catch{ $Result | Add-Member -MemberType NoteProperty -Name "Uptime (DD:HH:MM)" -Value "Unknown" } # Pending Reboot Try/Catch - clear pending reboot to avoid false positives $PendingReboot = $null try { $PendingReboot = (Get-PendingReboot -ComputerName $Computer -Credential $mycreds -ErrorAction Stop) if ($PendingReboot -eq "" -or $PendingReboot -eq "Unknown" -or $PendingReboot -eq "Pending Reboot") { #Write-Host $PendingReboot -BackgroundColor Red $Result | Add-Member -MemberType NoteProperty -Name "Pending Reboot" -Value $pendingreboot } elseif ($PendingReboot -eq "False") { $Result | Add-Member -MemberType NoteProperty -Name "Pending Reboot" -Value "" } else { $Result | Add-Member -MemberType NoteProperty -Name "Pending Reboot" -Value "Error" Write-LogError -LogPath $Log -Message “$Computer : Error: $_ ” -ErrorAction SilentlyContinue -TimeStamp | Out-Null } } catch { $Result | Add-Member -MemberType NoteProperty -Name "Pending Reboot Catch" -Value "Error" Write-LogError -LogPath $Log -Message “$Computer : Error: $_ ” -ErrorAction SilentlyContinue -TimeStamp | Out-Null } } } } else { # Computer doesn't even respond to ping..." $Result | Add-Member -MemberType NoteProperty -Name "Ping Result" -Value "Failed" } # Write this machine's results to the array $Results += $Result } # End for loop on the computer array # Export the array to the CSV report if ($WriteReport -eq $true) { $Results | Export-Csv -NoTypeInformation -Path "$ReportsDir\$Reportname" Write-Host "Report exported to $ReportsDir\$Reportname" -BackgroundColor DarkGreen } else { $Results | ft * } if ($ErrorLog) { Stop-Log -LogPath $Log Write-Host "Error log written to $log" } } |