Skip to content

Instantly share code, notes, and snippets.

@smurawski
Last active November 24, 2015 14:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save smurawski/6de63da2c9af6f4cf595 to your computer and use it in GitHub Desktop.
Save smurawski/6de63da2c9af6f4cf595 to your computer and use it in GitHub Desktop.
Module for comparing server roles and installed software.
function Compare-ServerRole
{
<#
.Synopsis
Compares the roles installed against a base server.
.Description
Compares the roles installed against a base server.
.Example
Compare-ServerRole ServerA ServerB
.Example
if (Compare-ServerRole ServerA ServerB -quiet) {DoSomething}
.Example
$InstalledRoles = Get-ServerRole ServerA, ServerB, ServerC ; Compare-ServerRole ServerA -InstalledRoles $InstalledRoles
#>
[cmdletbinding(DefaultParameterSetName='ByName')]
param (
[parameter(
parametersetname='ByHashtable',
position = 1,
mandatory = $true
)]
[System.Collections.Hashtable]
$InstalledRoles,
#Source Server
[parameter(
parametersetname='ByHashtable',
position = 0,
mandatory = $true
)]
[parameter(
parametersetname='ByName',
position = 0,
mandatory=$true
)]
[ValidateNotNullOrEmpty()]
[string]
$ReferenceServer,
#Target Server
[parameter(
parametersetname='ByName',
position = 1,
mandatory=$true
)]
[ValidateNotNullOrEmpty()]
$DifferenceServer,
#Alternate credentials to supply to the remote servers.
[parameter(
parametersetname='ByName'
)]
[System.Management.Automation.PSCredential]
$Credential = [System.Management.Automation.PSCredential]::Empty,
#Specifying this parameter will make the command return $true if the roles installed match
#and $false if there is a difference in the installed roles.
[parameter(
parametersetname='ByName'
)]
[switch]
$Quiet
)
end
{
if ($pscmdlet.ParameterSetName -like 'ByName')
{
$InstalledRoles = Get-ServerRole -ComputerName $ReferenceServer, $DifferenceServer -Credential $Credential
}
Compare-ServerDetail -DetailHashTable $InstalledRoles -ReferenceServer $ReferenceServer -Quiet:$Quiet
}
}
function Compare-InstalledSoftware
{
<#
.Synopsis
Compares the installed software against a base server.
.Description
Compares the installed software against a base server.
.Example
Compare-InstalledSoftware ServerA ServerB
.Example
if (Compare-InstalledSoftware ServerA ServerB -quiet) {DoSomething}
.Example
$InstalledSoftware = Get-InstalledSoftware ServerA, ServerB, ServerC ; Compare-InstalledSoftware ServerA -InstalledSoftware $InstalledSoftware
#>
[cmdletbinding(DefaultParameterSetName='ByName')]
param (
[parameter(
parametersetname='ByHashtable',
position = 1,
mandatory = $true
)]
[System.Collections.Hashtable]
$InstalledSoftware,
#Source Server
[parameter(
parametersetname='ByHashtable',
position = 0,
mandatory = $true
)]
[parameter(
parametersetname='ByName',
position = 0,
mandatory=$true
)]
[ValidateNotNullOrEmpty()]
[string]
$ReferenceServer,
#Target Server
[parameter(
parametersetname='ByName',
position = 1,
mandatory=$true
)]
[ValidateNotNullOrEmpty()]
$DifferenceServer,
#Alternate credentials to supply to the remote servers.
[parameter(
parametersetname='ByName'
)]
[System.Management.Automation.PSCredential]
$Credential = [System.Management.Automation.PSCredential]::Empty,
#Specifying this parameter will make the command return $true if the roles installed match
#and $false if there is a difference in the installed roles.
[parameter(
parametersetname='ByName'
)]
[switch]
$Quiet
)
end
{
if ($pscmdlet.ParameterSetName -like 'ByName')
{
$InstalledSoftware = Get-InstalledSoftware -ComputerName $ReferenceServer, $DifferenceServer -Credential $Credential
}
Compare-ServerDetail -DetailHashTable $InstalledSoftware -ReferenceServer $ReferenceServer -Quiet:$Quiet
}
}
function Get-ServerRole
{
<#
.Synopsis
Retrieves installed roles of supplied servers.
.Description
Retrieves installed roles of supplied servers.
Results are returned as a hashtable, with the key being the server name and the value being the results of Get-WindowsFeature.
.Example
$InstalledRoles = Get-ServerRole ServerA, ServerB, ServerC
#>
param (
#Servers to poll for roles.
[parameter(
mandatory,
position = 0
)]
[string[]]
$ComputerName,
#Alternate credentials to supply to the remote servers.
[parameter()]
[System.Management.Automation.PSCredential]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
try
{
$InstalledRoles = invoke-command -ErrorAction Stop @psboundparameters {
import-module ServerManager
Get-WindowsFeature |
Where-Object {$_.Installed}
}
$ReturnedRoles = @{}
foreach ($Computer in $ComputerName)
{
$ReturnedRoles.Add($Computer, ($InstalledRoles | Where-Object {$_.PSComputerName -like $Computer}))
}
return $ReturnedRoles
}
catch
{
throw "Failed to retrieve the roles. $($_.exception.message)."
}
}
function Get-InstalledSoftware
{
<#
.Synopsis
Retrieves installed software of supplied servers.
.Description
Retrieves installed software of supplied servers.
Results are returned as a hashtable, with the key being the server name and the value being metadata about the installed software.
.Example
$InstalledSoftware = Get-InstalledSoftware ServerA, ServerB, ServerC
#>
param (
#Servers to poll for roles.
[parameter(
mandatory,
position = 0
)]
[string[]]
$ComputerName,
#Alternate credentials to supply to the remote servers.
[parameter()]
[System.Management.Automation.PSCredential]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
try
{
$InstalledSoftware = invoke-command @PSBoundParameters {
$OSArchitecture = (Get-WMIObject win32_operatingSystem -ErrorAction Stop).OSArchitecture
if ($OSArchitecture -like '*64*') {
$RegistryPath = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
} else {
$RegistryPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall'
}
dir $RegistryPath |
Where-Object {($_.GetValue("DisplayName") -notmatch '(KB[0-9]{6,7})') -and ($_.GetValue("DisplayName") -ne $null)} |
foreach {
New-Object -TypeName PSObject -property @{
Name = $_.GetValue("DisplayName")
MajorVersion = $_.GetValue("VersionMajor")
MinorVersion = $_.GetValue("VersionMinor")
DisplayVersion = $_.GetValue("DisplayVersion")
}
}
}
$ReturnedSoftware = @{}
foreach ($Computer in $ComputerName)
{
$ReturnedSoftware.Add($Computer, ($InstalledSoftware | Where-Object {$_.PSComputerName -like $Computer}))
}
return $ReturnedSoftware
}
catch
{
throw "Failed to retrive the installed software."
}
}
function Compare-ServerDetail
{
param (
[parameter(
position = 0,
mandatory=$true
)]
[ValidateNotNullOrEmpty()]
[string]
$ReferenceServer,
[parameter(
position = 1,
mandatory = $true
)]
[System.Collections.Hashtable]
$DetailHashTable,
[parameter()]
[switch]
$Quiet
)
$SideIndicatorTransform = @{
n='PSComputerName'
e={
if ($_.SideIndicator -like '<=')
{
Write-Verbose "Found $($_.name) on $ReferenceServer but not $CurrentServer"
$ReferenceServer}
else
{
Write-Verbose "Found $($_.name) on $CurrentServer but not $ReferenceServer"
$CurrentServer
}
}
}
$CompareSideIndicatorTransform = @{
n='ComparedToComputerName'
e={
if ($_.SideIndicator -like '=>')
{
Write-Verbose "Found $($_.name) on $CurrentServer but not $ReferenceServer"
$ReferenceServer}
else
{
Write-Verbose "Found $($_.name) on $ReferenceServer but not $CurrentServer"
$CurrentServer
}
}
}
$CompareParameters = @{
ReferenceObject = $DetailHashTable[$ReferenceServer]
Property = 'Name'
}
$compare = $DetailHashTable.Keys |
Where-Object {$_ -notlike $ReferenceServer} |
Foreach-Object {
$CurrentServer = $_
Compare-Object -DifferenceObject $DetailHashTable[$CurrentServer] @CompareParameters |
Select-Object Name, $SideIndicatorTransform, $CompareSideIndicatorTransform
}
if ($Quiet -and $Compare)
{
return $false
}
elseif ($Quiet)
{
return $true
}
elseif ($compare)
{
return $Compare
}
else
{
return $null
}
}
Export-ModuleMember -Function 'Compare-InstalledSoftware', 'Compare-ServerRole', 'Get-InstalledSoftware', 'Get-ServerRole'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment