<#
.SYNOPSIS
QC.ps1 - PowerShell script for Quality check on server builds.
.DESCRIPTION
This PowerShell script runs a series of WMI and other queries to gather server build details.
.OUTPUTS
Each server(s) results are output to HTML.
.PARAMETER -Verbose
See more detailed progress as the script is running.
.EXAMPLE
.\QC.ps1 SERVER1
Performs Quality check on a single server.
.EXAMPLE
"SERVER1","SERVER2","SERVER3" | .\QC.ps1
Performs Quality check on multiple servers.
.EXAMPLE
Get-WmiObject Win32_OperatingSystem | % caption
Gathers OS version and Edition
Change Log:
V1.00, 1st March 2018 - First release
By:
RK
#>
[CmdletBinding()]
Param (
[parameter(ValueFromPipeline=$True)]
[string[]]$ComputerName
)
Begin
{
#Initialize
Write-Verbose "Initializing"
}
Process
{
#---------------------------------------------------------------------
# Process each ComputerName
#---------------------------------------------------------------------
if (!($PSCmdlet.MyInvocation.BoundParameters[“Verbose”].IsPresent))
{
Write-Host "Processing $ComputerName"
}
Write-Verbose "=====> Processing $ComputerName <====="
$htmlreport = @()
$htmlbody = @()
$htmlfile = "$($ComputerName).html"
$spacer = "<br />"
#---------------------------------------------------------------------
# Check Server Name & Domain and convert to HTML fragment
#---------------------------------------------------------------------
Write-Verbose "Collecting computer system information"
$subhead = "<th> 1.Server Name & FQDN: </th>"
$htmlbody += $subhead
try
{
$Nameinfo = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName -ErrorAction STOP |Select-Object Name,
@{Name='DNS Name';Exp={$_.DnsHostName}},
@{Name='FQDN';Exp={$_.Domain}}
$htmlbody += $Nameinfo| ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Server Make & Model and convert to HTML fragment
#---------------------------------------------------------------------
Write-Verbose "Collecting computer system information"
$subhead = "<th> 2.Server Make & Model: </th>"
$htmlbody += $subhead
try
{
$csinfo = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName -ErrorAction STOP |Select-Object Manufacturer,Model
$htmlbody += $csinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Collect BIOS information and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th>3.BIOS & Serial Number:</th>"
$htmlbody += $subhead
Write-Verbose "Collecting BIOS information"
try
{
$biosinfo = Get-WmiObject Win32_Bios -ComputerName $ComputerName -ErrorAction STOP |
Select-Object Status,Version,
@{Name='Release Date';Expression={
$releasedate = [datetime]::ParseExact($_.ReleaseDate.SubString(0,8),"yyyyMMdd",$null);
$releasedate.ToShortDateString()
}},
@{Name='Serial Number';Expression={$_.SerialNumber}}
$htmlbody += $biosinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check CPU Configuration and convert to HTML fragment
#---------------------------------------------------------------------
Write-Verbose "Collecting computer system information"
$subhead = "<th> 4.CPU Configuration: </th>"
$htmlbody += $subhead
try
{
$Cpuinfo = Get-WmiObject -Class Win32_Processor -ComputerName $ComputerName -ErrorAction STOP | Select-Object -Property DeviceID,SocketDesignation,Name,NumberOfCores,NumberOfLogicalProcessors
$htmlbody += $Cpuinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Memory Configuration and convert to HTML fragment
#---------------------------------------------------------------------
Write-Verbose "Collecting computer system information"
$subhead = "<th> 5.Memory Configuration: </th>"
$htmlbody += $subhead
try
{
$Meminfo = Get-WmiObject -Class Win32_PhysicalMemory -ComputerName $ComputerName -ErrorAction STOP |Select-Object Name,DeviceLocator,
@{Name='Physical Memory (Gb)';Expression={$_.Capacity/1GB}}
$htmlbody += $Meminfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Verify Operating System information and convert to HTML fragment
#---------------------------------------------------------------------
Write-Verbose "Verifying operating system information"
$subhead = "<th> 6.Operating System: </th>"
$htmlbody += $subhead
try
{
$osinfo = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName -ErrorAction STOP |
Select-Object @{Name='Operating System';Expression={$_.Caption}},
@{Name='Architecture';Expression={$_.OSArchitecture}},
Version
$htmlbody += $osinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Collect Network Interface Configuration and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 7.Network Interfaces: </th>"
$htmlbody += $subhead
Write-Verbose "Collecting Network Interface Configuration"
try
{
$nics = @()
$nicinfo = @(Get-WmiObject Win32_NetworkAdapter -Filter "NetEnabled=True" -ComputerName $ComputerName -ErrorAction STOP |Where {$_.PhysicalAdapter} |
Select-Object Name,AdapterType,MACAddress,
@{Name='ConnectionName';Expression={$_.NetConnectionID}},
@{Name='Enabled';Expression={$_.NetEnabled}},
@{Name='Speed';Expression={$_.Speed/1000000}})
foreach ($nic in $nicinfo)
{
$nicObject = New-Object PSObject
$nicObject | Add-Member NoteProperty -Name "Connection Name" -Value $nic.connectionname
$nicObject | Add-Member NoteProperty -Name "Adapter Name" -Value $nic.Name
$nicObject | Add-Member NoteProperty -Name "MAC" -Value $nic.MACAddress
$nicObject | Add-Member NoteProperty -Name "Speed (Mbps)" -Value $nic.Speed
$nics += $nicObject
}
$htmlbody += $nics | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Network Interface Configureation and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 8.Network Interface Configuration: </th>"
$htmlbody += $subhead
Write-Verbose "Checking Network Interface Configuration"
try
{
$adapters= Get-WmiObject Win32_NetworkAdapterConfiguration -filter "IPEnabled=true" -ComputerName $ComputerName -ErrorAction STOP | select-Object @{Name='Mac Address';Expression={$_.MACAddress}},
@{Name='IPAddress';Expression={$_.IPAddress}},
@{Name='Subnet Mask';Expression={$_.IPSubnet}},
@{Name='Default Gateway';Expression={$_.DefaultIPGateway}},
@{Name='DNS Server Search Order';Expression={$_.DNSServerSearchOrder}},
@{Name='WINSPrimaryServer';Expression={$_.WINSPrimaryServer }},
@{Name='WINSSecondaryServer';Expression={$_.WINSSecondaryServer}},
@{Name='DNS Registration Enable';Expression={$_.DomainDNSRegistrationEnabled}},
@{Name='DNS Suffix Search Order';Expression={$_.DNSDomainSuffixSearchOrder}},
@{Name='TCPIP Over Netbios';Exp={
switch ($_.TcpipNetbiosOptions)
{
0 {'Enabled via DHCP'}
1 {'Enabled'}
2 {'Disabled'}
}
#EndOfCaltulatedProperty
}}
$htmlbody += $adapters | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Collect logical disk information and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 9.Logical Drives: </th>"
$htmlbody += $subhead
Write-Verbose "Collecting logical disk information"
try
{
$diskinfo = Get-WmiObject -Class Win32_Volume -ComputerName $ComputerName -ErrorAction STOP | Select PSComputerName , DriveLetter , Label , Blocksize, @{Name=”size(GB)”;Expression={“{0:N1}” -f($_.Capacity/1gb)}}
$htmlbody += $diskinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Pagefile Settings and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 10.PageFile Configuration: </th>"
$htmlbody += $subhead
Write-Verbose "Collecting pagefile information"
try
{
$pagefileinfo = Get-WmiObject Win32_PageFileUsage -ComputerName $ComputerName -ErrorAction STOP |
Select-Object @{Name='Pagefile Name';Expression={$_.Name}},
@{Name='Allocated Size (Mb)';Expression={$_.AllocatedBaseSize}}
$htmlbody += $pagefileinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Time Zone Settings and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 11.Time Zone Configuration: </th>"
$htmlbody += $subhead
Write-Verbose "Collecting Time Zone Configuration"
try
{
$Timezoneinfo = Get-WMIObject -class Win32_TimeZone -ComputerName $ComputerName -ErrorAction STOP | Select-Object Bias*,Caption
$htmlbody += $Timezoneinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Local Accounts and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 12.Local Accounts: </th>"
$htmlbody += $subhead
Write-Verbose "Collecting Local Accounts"
try
{
$Localaccountsinfo = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True'" -ComputerName $ComputerName -ErrorAction STOP | Select-Object Domain,Name
$htmlbody += $Localaccountsinfo | ConvertTo-Html -Fragment
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Check Logical access and convert to HTML fragment
#---------------------------------------------------------------------
$subhead = "<th> 13.Logical Access(Admin Rights): </th>"
$htmlbody += $subhead
Write-Verbose "Collecting Logical access"
try
{
$admins = Gwmi win32_groupuser –computer $ComputerName
$admins = $admins |? {$_.groupcomponent –like '*"Administrators"'} | Select-Object PartComponent
$admins = $admins |% {
$_.partcomponent –match “.+Domain\=(.+)\,Name\=(.+)$” > $nul
$matches[1].trim('"') + “\” + $matches[2].trim('"')
}
$Logicalaccessinfo = &{$ofs='</BR>';[string]$admins}
$htmlbody += $spacer
$htmlbody += $Logicalaccessinfo
$htmlbody += $spacer
}
catch
{
Write-Warning $_.Exception.Message
$htmlbody += "<p>An error was encountered. $($_.Exception.Message)</p>"
$htmlbody += $spacer
}
#---------------------------------------------------------------------
# Generate the HTML report and output to file
#---------------------------------------------------------------------
Write-Verbose "Producing HTML report"
$reportime = Get-Date
$Req=Read-Host "Enter Request#"
$wo=Read-Host "Enter Work Order#"
#$pam= Read-Host "Enter PAM"
$reportime = Get-Date
#Common HTML head and styles
$htmlhead="<html>
<style>
BODY{font-family: Verdana; font-size: 14pt;background-color:#F5FFFA}
H1{font-size: 22px;}
H2{font-size: 20px;}
H3{font-size: 18px;}
TABLE{border: 1px solid black; border-collapse: collapse; font-size: 12pt;}
TH{border: 1px solid black; background: #dddddd; padding: 7px; color:White;background-color:#6495ED;}
TD{border: 1px solid black; padding: 7px;color:White;background-color:#3CB371;}
td.pass{background: #7FFF00;}
td.warn{background: #FFE600;}
td.fail{background: #FF0000; color: #ffffff;}
td.info{background: #85D4FF;}
</style>
<body>
<table align='Left'>
<thead>
<tr>
<th colspan=2><strong>Server Build Checklist</strong></th>
</tr>
<tr>
</tr>
<th>Generated on</th>
<th>$reportime
</tr>
<tr>
<th>Generated by</th>
<th>$env:USERNAME
</tr>
</table>
<table align='right'>
<tr>
<th>Request Number</th>
<th>$req
</tr>
<tr>
<th>Work Order Number</th>
<th>$wo
</tr>
</table>
<br><br><br><br><br><br><br>
</body>"
$htmltail = "</body>
</html>"
$htmlreport = $htmlhead + $htmlbody + $htmltail
$htmlreport | Out-File $htmlfile -Encoding Utf8
}
End
{
#Wrap it up
Write-Verbose "=====> Finished <====="
}
*********************************************************************************
use below command in cmd mention list of patch and Servername and run to get output.
********************************************************************************
Take a screenshot of disks layout / letters in order to re assign letters after OS reinstallation (eg. below)
Take a screenshot of network conf. setting for the configuration after server is rebuilt
Enter the server IP address, SubetMask, DefaultGateway, DNS etc ..
d select partition 4 (!double check ! you selected C drive correct partition number)
run following command to apply image (this example shows how to apply W2K12 WIM mage):
To ensure all the servers HW components are on the latest Firmware level / latest drivers are installed
please install latest drivers / FW from latest Service Pack for ProLiant.
*********************************************************************************