Retrieves IIS settings from remote machines and presents difference view in winmerge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Modules webadministration | |
#Requires -RunAsAdministrator | |
#Requires -version 3.0 | |
<# | |
.SYNOPSIS | |
Provides a means to get the current backup location for iis changes | |
.DESCRIPTION | |
Changes made to the IIS instance are recorded in a history config file. This function provides the means to retreive where it is on the machine | |
Get-IISSystemHistoryLocation -index '2' | |
.PARAMETER index | |
if a value for index is passed it'll get the x number from the collection of history backups. | |
For instance if there are 5 backups and the index number passed is 2 then It'll get the next backup from the latest. | |
.Example | |
PS PS:\> Get-IISSystemHistoryLocation -computerName test 0 | |
\\test\C$\inetpub\history\CFGHISTORY_0000000033 | |
.Example 2 | |
PS PS:\> Get-IISSystemHistoryLocation -computerName test 3 | |
\\test\C$\inetpub\history\CFGHISTORY_0000000030 | |
#> | |
function Get-IISSystemHistoryLocation | |
{ | |
[OutputType([string])] | |
param | |
( | |
[string]$computerName, | |
[Parameter(Mandatory = $false)] | |
[int16]$index = '1' | |
) | |
$computerName = Get-LocalRemoteComputer -computername $computerName | |
if($computerName -ne $env:COMPUTERNAME) | |
{ | |
$startingdir = Resolve-EnvVariable -String '%systemroot%' -computername $computername | |
} | |
else | |
{ | |
$startingdir = $env:windir | |
} | |
$config = [xml](get-content "$startingDir\system32\inetsrv\config\schema\IIS_schema.xml") | |
$configHistory = (($config.configSchema.sectionschema | where{ $_.name -like "*configHistory*" }).attribute | ?{ $_.name -like "path" }).defaultvalue | |
$envVar = $configHistory | Resolve-EnvVariable -computername $computername | |
$configDir = dir $envVar | Sort-Object -Property lastwritetime -Descending | select -Index $index | |
$configd = $configdir.fullname | |
$configd -match '\w:' | out-null | |
if($Matches) | |
{ | |
$driveLetter = ($Matches.values).trim(':') | |
$serverConfig = $configd -replace '\w:', "\\$computername\$driveletter$" | |
$configd = $serverConfig | |
} | |
$configd | |
} | |
<# | |
.SYNOPSIS | |
A brief description of the Resolve-EnvVariable function. | |
.DESCRIPTION | |
Takes an environment variable and resolves it to the actual location stripping off the %% from a dos command. | |
example | |
Resolve-EnvVariable -String %temp% -computername $computername | |
\\servername\C$\Users\TSCHUM~1\AppData\Local\Temp | |
Resolve-EnvVariable -String %temp% -computername . | |
C:\Users\TSCHUM~1\AppData\Local\Temp | |
.PARAMETER String | |
Enter a string that contains an environmental variable like %WINDIR% | |
.PARAMETER computername | |
Name of the computer to check the environment variable against. | |
#> | |
function Resolve-EnvVariable | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory = $true, | |
ValueFromPipeline = $true, | |
Position = 0, | |
HelpMessage = 'Enter a string that contains an environmental variable like %WINDIR%')] | |
[ValidateNotNullOrEmpty()] | |
[string]$String, | |
[string]$computername | |
) | |
#https://powershell.org/friday-fun-expand-environmental-variables-in-powershell-strings/ | |
Begin | |
{ | |
$computerName = Get-LocalRemoteComputer -computername $computerName | |
Write-Verbose "Starting $($myinvocation.mycommand)" | |
} #Begin | |
Process | |
{ | |
#if string contains a % then process it | |
if ($string -match "%\S+%") | |
{ | |
Write-Verbose "Resolving environmental variables in $String" | |
#split string into an array of values | |
$values = $string.split("%") | Where { $_ } | |
foreach ($text in $values) | |
{ | |
#find the corresponding value in ENV: | |
Write-Verbose "Looking for $text" | |
if ($env:COMPUTERNAME -ne $computername) | |
{ | |
[string]$replace = (invoke-command -ComputerName $computername -ScriptBlock { param ([string]$t)get-item env:$t -ErrorAction SilentlyContinue } -ArgumentList $text).value | |
#(Get-Item env:$text -erroraction "SilentlyContinue").Value | |
if ($replace) | |
{ | |
#if found append it to the new string | |
Write-Verbose "Found $replace" | |
$newstring += $replace | |
} | |
else | |
{ | |
#otherwise append the original text | |
$newstring += $text | |
} | |
$newstring -match '\w:' | out-null | |
if ($Matches) | |
{ | |
$driveLetter = ($Matches.values).trim(':') | |
$newstring = $newstring -replace '\w:', "\\$computername\$driveletter$" | |
} | |
} | |
else | |
{ | |
[string]$replace = (Get-Item env:$text -erroraction "SilentlyContinue").Value | |
if ($replace) | |
{ | |
#if found append it to the new string | |
Write-Verbose "Found $replace" | |
$newstring += $replace | |
} | |
else | |
{ | |
#otherwise append the original text | |
$newstring += $text | |
} | |
} | |
} #foreach value | |
Write-Verbose "Writing revised string to the pipeline" | |
#write the string back to the pipeline | |
Write-Output $NewString | |
} #if | |
else | |
{ | |
#skip the string and write it back to the pipeline | |
Write-Output $String | |
} | |
} #Process | |
End | |
{ | |
Write-Verbose "Ending $($myinvocation.mycommand)" | |
} #End | |
} #end Resolve-EnvVariable | |
<# | |
.SYNOPSIS | |
Gets the current backup location of IIS Configs | |
.DESCRIPTION | |
Gets the latest directory that contains the last IIS backup | |
If you do not specify an index number then the function will get index 0 of the number of backups. | |
Each backup in IIS is a seperate directory the script determines how many there are and sets the first index number to the most recent backup. | |
.PARAMETER computername | |
this is as string value that represents the comptutername that we want to find the backups for | |
.PARAMETER index | |
This is a integer(16) value that represents the index number of the backup you want to retrieve. the most recent backup is index 0. | |
.NOTES | |
This returns a string object of the backup location for the computername passed. | |
.Example | |
PS PS:\> Get-LastIISBackupLocation -computername test 1 | |
returns: \\test\C$\Windows\system32\inetsrv\backup\2016-07-14 | |
.Example 2 | |
PS PS:\> Get-LastIISBackupLocation -computername test 0 | |
\\test\C$\Windows\system32\inetsrv\backup\2016-07-15 | |
#> | |
function Get-LastIISBackupLocation | |
{ | |
[OutputType([string])] | |
param | |
( | |
[string]$computername, | |
[int16]$index = '0' | |
) | |
$computerName = Get-LocalRemoteComputer -computername $computerName | |
if ($computerName -ne $env:COMPUTERNAME) | |
{ | |
$startingdir = Resolve-EnvVariable -String '%systemroot%' -computername $computername | |
} | |
else | |
{ | |
$startingdir = $env:windir | |
} | |
$mostRecentDir = dir ("$startingdir\system32\inetsrv\backup") | Sort-Object -Property Lastwritetime -Descending | select -Index $index | |
$mostRecentDir.fullname | |
} | |
<# | |
.SYNOPSIS | |
Gets the current directory for the machine that is passed. | |
.DESCRIPTION | |
Gets the current installed location of iis from the IIS | |
.PARAMETER computername | |
string for computername that we want to find the current installation of iis | |
.EXAMPLE | |
Get-CurrentIISConfiguration -computername test | |
returns: \\test\c$\windows\system32\inetsrv\config | |
#> | |
function Get-CurrentIIsConfiguration | |
{ | |
[OutputType([string])] | |
param | |
( | |
[string]$computername | |
) | |
$computerName = Get-LocalRemoteComputer -computername $computerName | |
if ($computerName -ne $env:COMPUTERNAME) | |
{ | |
$startingdir = "\\$computername\c$\windows" | |
} | |
else | |
{ | |
$startingdir = $env:windir | |
} | |
$mostRecentDir = "$startingdir\system32\inetsrv\config" | |
$mostRecentDir | |
} | |
<# | |
.SYNOPSIS | |
Determines if the name passed is the localhost or not | |
.DESCRIPTION | |
If the name passed is the localhost then the script will send back the computername: | |
.example | |
get-localremotecomputer -computername . | |
yourmachinename | |
get-localremotecomputer -computername 127.0.0.1 | |
yourmachinename | |
get-localremotecomputer -computername servername | |
servername | |
.PARAMETER computername | |
A description of the computername parameter. | |
.NOTES | |
Additional information about the function. | |
#> | |
function Get-LocalRemoteComputer | |
{ | |
param | |
( | |
[string]$computername | |
) | |
if ($computername -eq '.' -or ($env:COMPUTERNAME -eq $computername) -or ($computername -eq 'Localhost') -or ($computername -eq '127.0.0.1')) | |
{ | |
$computername = $env:COMPUTERNAME | |
$computername | |
} | |
else | |
{ $computername } | |
} | |
<# | |
.SYNOPSIS | |
takes to files passed and sends them to winmerge for comparison | |
.DESCRIPTION | |
This function will pass the source and differnece file and then launch winmerge. | |
.PARAMETER sourceFile | |
file used to be the source of the comparison | |
.PARAMETER diffFile | |
file that is the difference file | |
.PARAMETER winMergeLoc | |
Physical location of the exe for winmerge. This function will pass the source and differnece file and then launch winmerge. | |
.NOTES | |
Additional information about the function. | |
#> | |
function Compare-IISConfigsWinMerge | |
{ | |
param | |
( | |
[string]$sourceFile, | |
[string]$diffFile, | |
[string]$winMergeLoc | |
) | |
if (test-path $winMergeLoc) | |
{ | |
if (test-path $sourcefile) | |
{ | |
if (test-path $difffile) | |
{ | |
& "$winmergeLoc " "$sourcefile " "$diffFile" | |
$results = $true | |
} | |
else { $results = 'bad diff file' } | |
} | |
else {$results = 'bad source file'} | |
} | |
else {$results = 'bad winmerge location' } | |
$results | |
} | |
$winmerge = '\\server\winmerge\WinMergePortable\winmergeportable.exe' | |
$history = Get-IISSystemHistoryLocation -computerName 'test' -index '2' | |
$current = Get-CurrentIIsConfiguration -computername 'test2' | |
Compare-IISConfigsWinMerge -winMergeLoc $winmerge -sourceFile "$current\applicationhost.config" -diffFile "$history\applicationHost.config" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment