function Repair-ValidIISPaths { <# .SYNOPSIS Ensure that all the paths in IIS are valid paths Performs No-Op until 'RemediateVirtualDirectories' switch is supplied .PARAMETER RemediateVirtualDirectories Remediate virtual directories to prevent errors #> [CmdletBinding()] param ( [switch]$RemediateVirtualDirectories ) $logLead = Get-LogLeadName if (-not (Test-Path -Path "IIS:")) { Write-Host "$logLead : IIS Drive not found, Run [Import-Module WebAdministration]" } # This hard-coded path will never change. We do not need to componentize it or anything into a separate function $configuration = ([xml](Get-Content -Path 'C:\Windows\System32\inetsrv\config\applicationHost.config')).configuration $emptyPath = Join-Path -Path (Get-OrbPath) -ChildPath "Empty" # Ensure the path exists if we will use it if ($RemediateVirtualDirectories) { if (-not (Test-Path -Path $emptyPath)) { Write-Host "$logLead : Creating [$emptyPath]" New-Item -ItemType Directory -Path $emptyPath -Force | Out-Null } } # Collect the data, because we should probably do a remediation # For now, alert on this information $failingApplicationPaths = @() $failingFailurePaths = @() foreach ($site in $configuration.'system.applicationHost'.sites.site) { foreach ($application in $site.application) { foreach ($virtualDirectory in $application.virtualdirectory) { $virtualDirectoryPhysicalPath = $virtualdirectory.physicalpath if ($virtualDirectoryPhysicalPath -eq "%SystemDrive%\inetpub\wwwroot") { Write-Verbose "$logLead : Skipping check for [$virtualDirectoryPhysicalPath]" Continue } if (-not (Test-Path -Path $virtualDirectoryPhysicalPath)) { $failingApplicationPaths += @{ Site = $site.name; ApplicationPool = $application.applicationPool; ApplicationPath = $application.path; Path = $virtualDirectoryPhysicalPath; } if ($RemediateVirtualDirectories) { Write-Host "$logLead : Path [$virtualDirectoryPhysicalPath] does not exist for ApplicationPool: [$($application.applicationPool)] at Virtual Dir path: [$($virtualDirectory.path)] under [$($site.name)], setting to [$emptyPath]" $iisPath = Join-Path -Path "IIS:\Sites\$($site.name)\$($application.path)" -ChildPath $virtualDirectory.path Set-ItemProperty $iisPath -Name physicalPath -Value $emptyPath } else { # TODO: TeamCity error? Write-Warning "$logLead : Path [$virtualDirectoryPhysicalPath] does not exist for [$($application.applicationPool)|$($virtualDirectory.path)] under [$($site.name)]" } } } } } foreach ($applicationPool in $configuration.'system.applicationHost'.applicationPools.add) { $appPoolFailureNodePhysicalPath = $applicationPool.failure.autoShutdownExe # Not all nodes have this configured if (Test-StringIsNullOrWhitespace -Value $appPoolFailureNodePhysicalPath) { continue } if (-not (Test-Path -Path $appPoolFailureNodePhysicalPath)) { Write-Warning "$logLead : Application pool [$($applicationPool.name)] has a configured failure/autoShutdownExe that is missing on disk [$appPoolFailureNodePhysicalPath]" $failingFailurePaths += @{ ApplicationPool = $applicationPool.name; Path = $appPoolFailureNodePhysicalPath; } # We should likely take an opportunity to find the sites/site/application that use this applicationPool to point out that it will break as well due to this } } }