DSCResources/MSFT_xWebAppPool/MSFT_xWebAppPool.psm1
# Load the Helper Module Import-Module $PSScriptRoot\..\Helper.psm1 -Verbose:$false data LocalizedData { # culture="en-US" ConvertFrom-StringData @' AppPoolNotFoundError = The requested AppPool "{0}" is not found on the target machine. AppPoolDiscoveryFailureError = Failure to get the requested AppPool "{0}" information from the target machine. AppPoolCreationFailureError = Failure to successfully create the AppPool "{0}". AppPoolRemovalFailureError = Failure to successfully remove the AppPool "{0}". AppPoolDiscoveryFailure = Multiple AppPools contain the name "{0}". Unable to continue. AppPoolCompareFailureError = Failure to successfully compare properties for AppPool "{0}". AppPoolStateFailureError = Failure to successfully set the state of the AppPool {0}. SetTargetResourceUnInstallwhatIfMessage = Trying to remove AppPool "{0}". SetTargetResourceInstallwhatIfMessage = Trying to create AppPool "{0}". TestEnsureState = The Ensure state for AppPool "{0}" does not match the desired state. TestStateConfig = State of AppPool "{0}" does not match the desired state. TestAutoStartConfig = AutoStart of AppPool "{0}" does not match the desired state. TestmanagedRuntimeVersionConfig = managedRuntimeVersion of AppPool "{0}" does not match the desired state. TestmanagedPipelineModeConfig = managedPipelineMode of AppPool "{0}" does not match the desired state. TeststartModeConfig = startMode of AppPool "{0}" does not match the desired state. TestidentityTypeConfig = identityType of AppPool "{0}" does not match the desired state. TestuserNameConfig = userName of AppPool "{0}" does not match the desired state. TestPasswordConfig = Password of AppPool "{0}" does not match the desired state. TestloadUserProfileConfig = loadUserProfile of AppPool "{0}" does not match the desired state. TestqueueLengthConfig = queueLength of AppPool "{0}" does not match the desired state. Testenable32BitAppOnWin64Config = enable32BitAppOnWin64 of AppPool "{0}" does not match the desired state. TestmanagedRuntimeLoaderConfig = managedRuntimeLoader of AppPool "{0}" does not match the desired state. TestenableConfigurationOverrideConfig = enableConfigurationOverride of AppPool "{0}" does not match the desired state. TestCLRConfigFileConfig = CLRConfigFile of AppPool "{0}" does not match the desired state. TestpassAnonymousTokenConfig = passAnonymousToken of AppPool "{0}" does not match the desired state. TestlogonTypeConfig = logonType of AppPool "{0}" does not match the desired state. TestmanualGroupMembershipConfig = manualGroupMembership of AppPool "{0}" does not match the desired state. TestidleTimeoutConfig = idleTimeout of AppPool "{0}" does not match the desired state. TestmaxProcessesConfig = maxProcesses of AppPool "{0}" does not match the desired state. TestshutdownTimeLimitConfig = shutdownTimeLimit of AppPool "{0}" does not match the desired state. TeststartupTimeLimitConfig = startupTimeLimit of AppPool "{0}" does not match the desired state. TestpingingEnabledConfig = pingingEnabled of AppPool "{0}" does not match the desired state. TestpingIntervalConfig = pingInterval of AppPool "{0}" does not match the desired state. TestpingResponseTimeConfig = pingResponseTime of AppPool "{0}" does not match the desired state. TestdisallowOverlappingRotationConfig = disallowOverlappingRotation of AppPool "{0}" does not match the desired state. TestdisallowRotationOnConfigChangeConfig = disallowRotationOnConfigChange of AppPool "{0}" does not match the desired state. TestlogEventOnRecycleConfig = logEventOnRecycle of AppPool "{0}" does not match the desired state. TestrestartMemoryLimitConfig = restartMemoryLimit of AppPool "{0}" does not match the desired state. TestrestartPrivateMemoryLimitConfig = restartPrivateMemoryLimit of AppPool "{0}" does not match the desired state. TestrestartRequestsLimitConfig = restartRequestsLimit of AppPool "{0}" does not match the desired state. TestrestartTimeLimitConfig = restartTimeLimit of AppPool "{0}" does not match the desired state. TestloadBalancerCapabilitiesConfig = loadBalancerCapabilities of AppPool "{0}" does not match the desired state. TestorphanWorkerProcessConfig = orphanWorkerProcess of AppPool "{0}" does not match the desired state. TestorphanActionExeConfig = orphanActionExe of AppPool "{0}" does not match the desired state. TestorphanActionParamsConfig = orphanActionParams of AppPool "{0}" does not match the desired state. TestrapidFailProtectionConfig = rapidFailProtection of AppPool "{0}" does not match the desired state. TestrapidFailProtectionIntervalConfig = rapidFailProtectionInterval of AppPool "{0}" does not match the desired state. TestrapidFailProtectionMaxCrashesConfig = rapidFailProtectionMaxCrashes of AppPool "{0}" does not match the desired state. TestautoShutdownExeConfig = autoShutdownExe of AppPool "{0}" does not match the desired state. TestautoShutdownParamsConfig = autoShutdownParams of AppPool "{0}" does not match the desired state. TestcpuLimitConfig = cpuLimit of AppPool "{0}" does not match the desired state. TestcpuActionConfig = cpuAction of AppPool "{0}" does not match the desired state. TestcpuResetIntervalConfig = cpuResetInterval of AppPool "{0}" does not match the desired state. TestcpuSmpAffinitizedConfig = cpuSmpAffinitized of AppPool "{0}" does not match the desired state. TestcpuSmpProcessorAffinityMaskConfig = cpuSmpProcessorAffinityMask of AppPool "{0}" does not match the desired state. TestcpuSmpProcessorAffinityMask2Config = cpuSmpProcessorAffinityMask2 of AppPool "{0}" does not match the desired state. '@ } # The Get-TargetResource cmdlet is used to fetch the status of role or AppPool on the target machine. # It gives the AppPool info of the requested role/feature on the target machine. function Get-TargetResource { [OutputType([Hashtable])] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Name ) Assert-Module $AppPools = Invoke-AppCmd -Arguments list,apppool,$Name if ($AppPools.Count -eq 0) # No AppPool exists with this name. { $ensureResult = 'Absent'; } elseif ($AppPools.Count -eq 1) # A single AppPool exists with this name. { $ensureResult = 'Present' $AppPoolState = Invoke-AppCmd -Arguments list,apppool,$Name,/text:state [xml] $PoolConfig = Invoke-AppCmd -Arguments list,apppool,$Name,/config:* if ($PoolConfig.add.processModel.userName) { $AppPoolPassword = $PoolConfig.add.processModel.password | ConvertTo-SecureString -AsPlainText -Force $AppPoolCred = New-Object ` -TypeName System.Management.Automation.PSCredential ` -ArgumentList $($PoolConfig.add.processModel.userName, $AppPoolPassword) } else { $AppPoolCred = $null } } else # Multiple AppPools with the same name exist. This is not supported and is an error { $errorId = 'AppPoolDiscoveryFailure'; $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidResult $errorMessage = $($LocalizedData.AppPoolDiscoveryFailure) -f ${Name} $exception = New-Object System.InvalidOperationException $errorMessage $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord); } # Add all Website properties to the hash table return [ordered] @{ Name = $Name; Ensure = $ensureResult; State = $AppPoolState; Credential = $AppPoolCred; autoStart = $PoolConfig.add.autoStart; managedRuntimeVersion = $PoolConfig.add.managedRuntimeVersion; managedPipelineMode = $PoolConfig.add.managedPipelineMode; startMode = $PoolConfig.add.startMode; identityType = $PoolConfig.add.processModel.identityType; loadUserProfile = $PoolConfig.add.processModel.loadUserProfile; queueLength = $PoolConfig.add.queueLength; enable32BitAppOnWin64 = $PoolConfig.add.enable32BitAppOnWin64; managedRuntimeLoader = $PoolConfig.add.managedRuntimeLoader; enableConfigurationOverride = $PoolConfig.add.enableConfigurationOverride; CLRConfigFile = $PoolConfig.add.CLRConfigFile; passAnonymousToken = $PoolConfig.add.passAnonymousToken; logonType = $PoolConfig.add.processModel.logonType; manualGroupMembership = $PoolConfig.add.processModel.manualGroupMembership; idleTimeout = $PoolConfig.add.processModel.idleTimeout; maxProcesses = $PoolConfig.add.processModel.maxProcesses; shutdownTimeLimit = $PoolConfig.add.processModel.shutdownTimeLimit; startupTimeLimit = $PoolConfig.add.processModel.startupTimeLimit; pingingEnabled = $PoolConfig.add.processModel.pingingEnabled; pingInterval = $PoolConfig.add.processModel.pingInterval; pingResponseTime = $PoolConfig.add.processModel.pingResponseTime; disallowOverlappingRotation = $PoolConfig.add.recycling.disallowOverlappingRotation; disallowRotationOnConfigChange = $PoolConfig.add.recycling.disallowRotationOnConfigChange; logEventOnRecycle = $PoolConfig.add.recycling.logEventOnRecycle; restartMemoryLimit = $PoolConfig.add.recycling.periodicRestart.memory; restartPrivateMemoryLimit = $PoolConfig.add.recycling.periodicRestart.privateMemory; restartRequestsLimit = $PoolConfig.add.recycling.periodicRestart.requests; restartTimeLimit = $PoolConfig.add.recycling.periodicRestart.time; restartSchedule = @($PoolConfig.add.recycling.periodicRestart.schedule.add.value); loadBalancerCapabilities = $PoolConfig.add.failure.loadBalancerCapabilities; orphanWorkerProcess = $PoolConfig.add.failure.orphanWorkerProcess; orphanActionExe = $PoolConfig.add.failure.orphanActionExe; orphanActionParams = $PoolConfig.add.failure.orphanActionParams; rapidFailProtection = $PoolConfig.add.failure.rapidFailProtection; rapidFailProtectionInterval = $PoolConfig.add.failure.rapidFailProtectionInterval; rapidFailProtectionMaxCrashes = $PoolConfig.add.failure.rapidFailProtectionMaxCrashes; autoShutdownExe = $PoolConfig.add.failure.autoShutdownExe; autoShutdownParams = $PoolConfig.add.failure.autoShutdownParams; cpuLimit = $PoolConfig.add.cpu.limit; cpuAction = $PoolConfig.add.cpu.action; cpuResetInterval = $PoolConfig.add.cpu.resetInterval; cpuSmpAffinitized = $PoolConfig.add.cpu.smpAffinitized; cpuSmpProcessorAffinityMask = $PoolConfig.add.cpu.smpProcessorAffinityMask; cpuSmpProcessorAffinityMask2 = $PoolConfig.add.cpu.smpProcessorAffinityMask2; } } # The Set-TargetResource cmdlet is used to create, delete or configure a website on the target machine. function Set-TargetResource { [CmdletBinding(SupportsShouldProcess=$true)] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Name, [ValidateSet('Present', 'Absent')] [string] $Ensure = 'Present', [ValidateSet('Started','Stopped')] [string] $state = 'Started', [ValidateSet('true','false')] [string] $autoStart = 'true', [ValidateSet('v4.0','v2.0','')] [string] $managedRuntimeVersion = 'v4.0', [ValidateSet('Integrated','Classic')] [string] $managedPipelineMode = 'Integrated', [ValidateSet('AlwaysRunning','OnDemand')] [string] $startMode = 'OnDemand', [ValidateSet('ApplicationPoolIdentity','LocalSystem','LocalService','NetworkService','SpecificUser')] [string] $identityType = 'ApplicationPoolIdentity', [System.Management.Automation.PSCredential] $Credential, [ValidateSet('true','false')] [string] $loadUserProfile = 'true', [string] $queueLength = '1000', [ValidateSet('true','false')] [string] $enable32BitAppOnWin64 = 'false', [string] $managedRuntimeLoader = 'webengine4.dll', [ValidateSet('true','false')] [string] $enableConfigurationOverride = 'true', [string] $CLRConfigFile = '', [ValidateSet('true','false')] [string] $passAnonymousToken = 'true', [ValidateSet('LogonBatch','LogonService')] [string] $logonType = 'LogonBatch', [ValidateSet('true','false')] [string] $manualGroupMembership = 'false', #Format 00:20:00 [string] $idleTimeout = '00:20:00', [string] $maxProcesses = '1', #Format 00:20:00 [string] $shutdownTimeLimit = '00:01:30', #Format 00:20:00 [string] $startupTimeLimit = '00:01:30', [ValidateSet('true','false')] [string] $pingingEnabled = 'true', #Format 00:20:00 [string] $pingInterval = '00:00:30', #Format 00:20:00 [string] $pingResponseTime = '00:01:30', [ValidateSet('true','false')] [string] $disallowOverlappingRotation = 'false', [ValidateSet('true','false')] [string] $disallowRotationOnConfigChange = 'false', #format 'Time, Memory, PrivateMemory' [string] $logEventOnRecycle = 'Time, Memory, PrivateMemory', [string] $restartMemoryLimit = '0', [string] $restartPrivateMemoryLimit = '0', [string] $restartRequestsLimit = '0', [string] $restartTimeLimit = '1.05:00:00', #Format 00:00:00 24hr clock and must have 00 for seconds [string[]] $restartSchedule = @(''), [ValidateSet('HttpLevel','TcpLevel')] [string] $loadBalancerCapabilities = 'HttpLevel', [ValidateSet('true','false')] [string] $orphanWorkerProcess = 'false', [string] $orphanActionExe = '', [string] $orphanActionParams = '', [ValidateSet('true','false')] [string] $rapidFailProtection = 'true', #Format 00:20:00 [string] $rapidFailProtectionInterval = '00:05:00', [string] $rapidFailProtectionMaxCrashes = '5', [string] $autoShutdownExe = '', [string] $autoShutdownParams = '', [string] $cpuLimit = '0', [ValidateSet('NoAction','KillW3wp','Throttle','ThrottleUnderLoad')] [string] $cpuAction = 'NoAction', #Format 00:20:00 [string] $cpuResetInterval = '00:05:00', [ValidateSet('true','false')] [string] $cpuSmpAffinitized = 'false', [string] $cpuSmpProcessorAffinityMask = '4294967295', [string] $cpuSmpProcessorAffinityMask2 = '4294967295' ) Write-Verbose "Begining Set-TargetResource" if ($Ensure -eq 'Present') { # Remove Ensure from parameters as it is not needed to create new AppPool $Result = $psboundparameters.Remove('Ensure'); Write-Verbose -Message 'Asserting WebAdministration is installed' # Check if WebAdministration module is present for IIS cmdlets Assert-Module $AppPool = Invoke-AppCmd -Arguments list,apppool,$Name # AppPool doesn't exist so create a new one if ($AppPool -eq $null) { try { New-WebAppPool -Name $Name Wait-Event -Timeout 5 Stop-WebAppPool -Name $Name Write-Verbose("successfully created AppPool $Name") #Start site if required if ($autoStart -eq 'true') { Start-WebAppPool $Name } Write-Verbose('successfully started AppPool $Name') $AppPool = Invoke-AppCmd -Arguments list,apppool,$Name } catch { $errorId = 'AppPoolCreationFailure'; $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; $errorMessage = $($LocalizedData.FeatureCreationFailureError) -f ${Name} ; $exception = New-Object System.InvalidOperationException $errorMessage ; $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord); } } if ($AppPool -ne $null) { # update parameters as required $UpdateNotRequired = $true # get configuration of AppPool [xml] $PoolConfig = Invoke-AppCmd -Arguments list,apppool,$Name,/config:* $AppPoolState = Invoke-AppCmd -Arguments list,apppool,$Name,/text:state #Update autoStart if required if ($PoolConfig.add.autoStart -ne $autoStart) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/autoStart:$autoStart } #update managedRuntimeVersion if required if ($PoolConfig.add.managedRuntimeVersion -ne $managedRuntimeVersion) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/managedRuntimeVersion:$managedRuntimeVersion } #update managedPipelineMode if required if ($PoolConfig.add.managedPipelineMode -ne $managedPipelineMode) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/managedPipelineMode:$managedPipelineMode } #update state if required if ($AppPoolState -ne $state) { $UpdateNotRequired = $false if ($State -eq 'Started') { Start-WebAppPool -Name $Name } else { Stop-WebAppPool -Name $Name } } #update startMode if required if ($PoolConfig.add.startMode -ne $startMode) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/startMode:$startMode } #update identityType if required if ($PoolConfig.add.processModel.identityType -ne $identityType) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.identityType:$identityType } #update userName if required #update password if required if ($identityType -eq 'SpecificUser' -and $Credential) { if ($PoolConfig.add.processModel.userName -ne $Credential.UserName) { $UpdateNotRequired = $false $userName = $($Credential.UserName) Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.userName:$userName } $clearTextPassword = $Credential.GetNetworkCredential().Password if ($clearTextPassword -cne $PoolConfig.add.processModel.password) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.password:$clearTextPassword } } # update loadUserProfile if required if ($PoolConfig.add.processModel.loadUserProfile -ne $loadUserProfile) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.loadUserProfile:$loadUserProfile } # update queueLength if required if ($PoolConfig.add.queueLength -ne $queueLength) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/queueLength:$queueLength } # update enable32BitAppOnWin64 if required if ($PoolConfig.add.enable32BitAppOnWin64 -ne $enable32BitAppOnWin64) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/enable32BitAppOnWin64:$enable32BitAppOnWin64 } # update managedRuntimeLoader if required if ($PoolConfig.add.managedRuntimeLoader -ne $managedRuntimeLoader) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/managedRuntimeLoader:$managedRuntimeLoader } # update enableConfigurationOverride if required if ($PoolConfig.add.enableConfigurationOverride -ne $enableConfigurationOverride) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/enableConfigurationOverride:$enableConfigurationOverride } # update CLRConfigFile if required if ($PoolConfig.add.CLRConfigFile -ne $CLRConfigFile) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/CLRConfigFile:$CLRConfigFile } # update passAnonymousToken if required if ($PoolConfig.add.passAnonymousToken -ne $passAnonymousToken) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/passAnonymousToken:$passAnonymousToken } #update logonType if required if ($PoolConfig.add.processModel.logonType -ne $logonType) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.logonType:$logonType } #update manualGroupMembership if required if ($PoolConfig.add.processModel.manualGroupMembership -ne $manualGroupMembership) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.manualGroupMembership:$manualGroupMembership } #update idleTimeout if required if ($PoolConfig.add.processModel.idleTimeout -ne $idleTimeout) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.idleTimeout:$idleTimeout } #update maxProcesses if required if ($PoolConfig.add.processModel.maxProcesses -ne $maxProcesses) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.maxProcesses:$maxProcesses } #update shutdownTimeLimit if required if ($PoolConfig.add.processModel.shutdownTimeLimit -ne $shutdownTimeLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.shutdownTimeLimit:$shutdownTimeLimit } #update startupTimeLimit if required if ($PoolConfig.add.processModel.startupTimeLimit -ne $startupTimeLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.startupTimeLimit:$startupTimeLimit } #update pingingEnabled if required if ($PoolConfig.add.processModel.pingingEnabled -ne $pingingEnabled) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.pingingEnabled:$pingingEnabled } #update pingInterval if required if ($PoolConfig.add.processModel.pingInterval -ne $pingInterval) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.pingInterval:$pingInterval } #update pingResponseTime if required if ($PoolConfig.add.processModel.pingResponseTime -ne $pingResponseTime) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/processModel.pingResponseTime:$pingResponseTime } #update disallowOverlappingRotation if required if ($PoolConfig.add.recycling.disallowOverlappingRotation -ne $disallowOverlappingRotation) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.disallowOverlappingRotation:$disallowOverlappingRotation } #update disallowRotationOnConfigChange if required if ($PoolConfig.add.recycling.disallowRotationOnConfigChange -ne $disallowRotationOnConfigChange) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.disallowRotationOnConfigChange:$disallowRotationOnConfigChange } #update logEventOnRecycle if required if ($PoolConfig.add.recycling.logEventOnRecycle -ne $logEventOnRecycle) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.logEventOnRecycle:$logEventOnRecycle } #update restartMemoryLimit if required if ($PoolConfig.add.recycling.periodicRestart.memory -ne $restartMemoryLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.periodicRestart.memory:$restartMemoryLimit } #update restartPrivateMemoryLimit if required if ($PoolConfig.add.recycling.periodicRestart.privateMemory -ne $restartPrivateMemoryLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.periodicRestart.privateMemory:$restartPrivateMemoryLimit } #update restartRequestsLimit if required if ($PoolConfig.add.recycling.periodicRestart.requests -ne $restartRequestsLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.periodicRestart.requests:$restartRequestsLimit } #update restartTimeLimit if required if ($PoolConfig.add.recycling.periodicRestart.time -ne $restartTimeLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/recycling.periodicRestart.time:$restartTimeLimit } #clear current schedule foreach($schTime in $PoolConfig.add.recycling.periodicRestart.schedule.add.value) { Invoke-AppCmd -Arguments set,apppool,$Name,"/-recycling.periodicRestart.schedule.[value='$schTime']" } #update restartSchedule if required #add desired schedule foreach($time in $restartSchedule) { Invoke-AppCmd -Arguments set,apppool,$Name,"/+recycling.periodicRestart.schedule.[value='$time']" } #update loadBalancerCapabilities if required if ($PoolConfig.add.failure.loadBalancerCapabilities -ne $loadBalancerCapabilities) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.loadBalancerCapabilities:$loadBalancerCapabilities } #update orphanWorkerProcess if required if ($PoolConfig.add.failure.orphanWorkerProcess -ne $orphanWorkerProcess) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.orphanWorkerProcess:$orphanWorkerProcess } #update orphanActionExe if required if ($PoolConfig.add.failure.orphanActionExe -ne $orphanActionExe) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.orphanActionExe:$orphanActionExe } #update orphanActionParams if required if ($PoolConfig.add.failure.orphanActionParams -ne $orphanActionParams) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.orphanActionParams:$orphanActionParams } #update rapidFailProtection if required if ($PoolConfig.add.failure.rapidFailProtection -ne $rapidFailProtection) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.rapidFailProtection:$rapidFailProtection } #update rapidFailProtectionInterval if required if ($PoolConfig.add.failure.rapidFailProtectionInterval -ne $rapidFailProtectionInterval) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.rapidFailProtectionInterval:$rapidFailProtectionInterval } #update rapidFailProtectionMaxCrashes if required if ($PoolConfig.add.failure.rapidFailProtectionMaxCrashes -ne $rapidFailProtectionMaxCrashes) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.rapidFailProtectionMaxCrashes:$rapidFailProtectionMaxCrashes } #update autoShutdownExe if required if ($PoolConfig.add.failure.autoShutdownExe -ne $autoShutdownExe) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.autoShutdownExe:$autoShutdownExe } #update autoShutdownParams if required if ($PoolConfig.add.failure.autoShutdownParams -ne $autoShutdownParams) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/failure.autoShutdownParams:$autoShutdownParams } #update cpuLimit if required if ($PoolConfig.add.cpu.limit -ne $cpuLimit) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/cpu.limit:$cpuLimit } #update cpuAction if required if ($PoolConfig.add.cpu.action -ne $cpuAction) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/cpu.action:$cpuAction } #update cpuResetInterval if required if ($PoolConfig.add.cpu.resetInterval -ne $cpuResetInterval) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/cpu.resetInterval:$cpuResetInterval } #update cpuSmpAffinitized if required if ($PoolConfig.add.cpu.smpAffinitized -ne $cpuSmpAffinitized) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/cpu.smpAffinitized:$cpuSmpAffinitized } #update cpuSmpProcessorAffinityMask if required if ($PoolConfig.add.cpu.smpProcessorAffinityMask -ne $cpuSmpProcessorAffinityMask) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/cpu.smpProcessorAffinityMask:$cpuSmpProcessorAffinityMask } #update cpuSmpProcessorAffinityMask2 if required if ($PoolConfig.add.cpu.smpProcessorAffinityMask2 -ne $cpuSmpProcessorAffinityMask2) { $UpdateNotRequired = $false Invoke-AppCmd -Arguments set,apppool,$Name,/cpu.smpProcessorAffinityMask2:$cpuSmpProcessorAffinityMask2 } if ($UpdateNotRequired) { Write-Verbose('AppPool $Name already exists and properties do not need to be updated.'); } } } else #Ensure is set to 'Absent' so remove website { try { $AppPool = Invoke-AppCmd -Arguments list,apppool,$Name if ($AppPool -ne $null) { Stop-WebAppPool $Name Remove-WebAppPool $Name Write-Verbose('Successfully removed AppPool $Name.') } else { Write-Verbose('AppPool $Name does not exist.') } } catch { $errorId = 'AppPoolRemovalFailure'; $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; $errorMessage = $($LocalizedData.WebsiteRemovalFailureError) -f ${Name} ; $exception = New-Object System.InvalidOperationException $errorMessage ; $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord); } } } # The Test-TargetResource cmdlet is used to validate if the role or feature is in a state as expected in the instance document. function Test-TargetResource { [OutputType([bool])] param ( [ValidateSet('Present', 'Absent')] [string] $Ensure = 'Present', [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Name, [ValidateSet('Started','Stopped')] [string] $state = 'Started', [ValidateSet('true','false')] [string] $autoStart = 'true', [ValidateSet('v4.0','v2.0','')] [string] $managedRuntimeVersion = 'v4.0', [ValidateSet('Integrated','Classic')] [string] $managedPipelineMode = 'Integrated', [ValidateSet('AlwaysRunning','OnDemand')] [string] $startMode = 'OnDemand', [ValidateSet('ApplicationPoolIdentity','LocalSystem','LocalService','NetworkService','SpecificUser')] [string] $identityType = 'ApplicationPoolIdentity', [System.Management.Automation.PSCredential] $Credential, [ValidateSet('true','false')] [string] $loadUserProfile = 'true', [string] $queueLength = '1000', [ValidateSet('true','false')] [string] $enable32BitAppOnWin64 = 'false', [string] $managedRuntimeLoader = 'webengine4.dll', [ValidateSet('true','false')] [string] $enableConfigurationOverride = 'true', [string] $CLRConfigFile = '', [ValidateSet('true','false')] [string] $passAnonymousToken = 'true', [ValidateSet('LogonBatch','LogonService')] [string] $logonType = 'LogonBatch', [ValidateSet('true','false')] [string] $manualGroupMembership = 'false', #Format 00:20:00 [string] $idleTimeout = '00:20:00', [string] $maxProcesses = '1', #Format 00:20:00 [string] $shutdownTimeLimit = '00:01:30', #Format 00:20:00 [string] $startupTimeLimit = '00:01:30', [ValidateSet('true','false')] [string] $pingingEnabled = 'true', #Format 00:20:00 [string] $pingInterval = '00:00:30', #Format 00:20:00 [string] $pingResponseTime = '00:01:30', [ValidateSet('true','false')] [string] $disallowOverlappingRotation = 'false', [ValidateSet('true','false')] [string] $disallowRotationOnConfigChange = 'false', #format 'Time, Memory, PrivateMemory' [string] $logEventOnRecycle = 'Time, Memory, PrivateMemory', [string] $restartMemoryLimit = '0', [string] $restartPrivateMemoryLimit = '0', [string] $restartRequestsLimit = '0', [string] $restartTimeLimit = '1.05:00:00', #Format 00:00:00 24hr clock and must have 00 for seconds [string[]] $restartSchedule = @(''), [ValidateSet('HttpLevel','TcpLevel')] [string] $loadBalancerCapabilities = 'HttpLevel', [ValidateSet('true','false')] [string] $orphanWorkerProcess = 'false', [string] $orphanActionExe = '', [string] $orphanActionParams = '', [ValidateSet('true','false')] [string] $rapidFailProtection = 'true', #Format 00:20:00 [string] $rapidFailProtectionInterval = '00:05:00', [string] $rapidFailProtectionMaxCrashes = '5', [string] $autoShutdownExe = '', [string] $autoShutdownParams = '', [string] $cpuLimit = '0', [ValidateSet('NoAction','KillW3wp','Throttle','ThrottleUnderLoad')] [string] $cpuAction = 'NoAction', #Format 00:20:00 [string] $cpuResetInterval = '00:05:00', [ValidateSet('true','false')] [string] $cpuSmpAffinitized = 'false', [string] $cpuSmpProcessorAffinityMask = '4294967295', [string] $cpuSmpProcessorAffinityMask2 = '4294967295' ) $DesiredConfigurationMatch = $true Assert-Module $AppPool = Invoke-AppCmd -Arguments list,apppool,$Name if ($AppPool) { [xml] $PoolConfig = Invoke-AppCmd -Arguments list,apppool,$Name,/config:* $AppPoolState = Invoke-AppCmd -Arguments list,apppool,$Name,/text:state } $Stop = $true Do { #Check Ensure if (($Ensure -eq 'Present' -and $AppPool -eq $null) -or ($Ensure -eq 'Absent' -and $AppPool -ne $null)) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestEnsureState'] -f $Name) break } # Only check properties if $AppPool exists if ($AppPool -ne $null) { # Check state if ($AppPoolState -ne $State) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestStateConfig'] -f $Name) break } # Check autoStart if ($PoolConfig.add.autoStart -ne $autoStart) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestAutoStartConfig'] -f $Name) break } # Check managedRuntimeVersion if ($PoolConfig.add.managedRuntimeVersion -ne $managedRuntimeVersion) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestmanagedRuntimeVersionConfig'] -f $Name) break } # Check managedPipelineMode if ($PoolConfig.add.managedPipelineMode -ne $managedPipelineMode) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestmanagedPipelineModeConfig'] -f $Name) break } # Check startMode if ($PoolConfig.add.startMode -ne $startMode) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TeststartModeConfig'] -f $Name) break } # Check identityType if ($PoolConfig.add.processModel.identityType -ne $identityType) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestidentityTypeConfig'] -f $Name) break } # Check userName/password if ($identityType -eq "SpecificUser" -and $Credential) { if ($PoolConfig.add.processModel.userName -ne $Credential.UserName) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestuserNameConfig'] -f $Name) break } $clearTextPassword = $Credential.GetNetworkCredential().Password if ($clearTextPassword -cne $PoolConfig.add.processModel.password) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestPasswordConfig'] -f $Name) break } } # Check loadUserProfile if ($PoolConfig.add.processModel.loadUserProfile -ne $loadUserProfile) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestLoadUserProfileConfig'] -f $Name) break } # Check queueLength if ($PoolConfig.add.queueLength -ne $queueLength) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestqueueLengthConfig'] -f $Name) break } # Check enable32BitAppOnWin64 if ($PoolConfig.add.enable32BitAppOnWin64 -ne $enable32BitAppOnWin64) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['Testenable32BitAppOnWin64Config'] -f $Name) break } # Check managedRuntimeLoader if ($PoolConfig.add.managedRuntimeLoader -ne $managedRuntimeLoader) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestmanagedRuntimeLoaderConfig'] -f $Name) break } # Check enableConfigurationOverride if ($PoolConfig.add.enableConfigurationOverride -ne $enableConfigurationOverride) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testenableConfigurationOverrideConfig'] -f $Name) break } # Check CLRConfigFile if ($PoolConfig.add.CLRConfigFile -ne $CLRConfigFile) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testCLRConfigFileConfig'] -f $Name) break } # Check passAnonymousToken if ($PoolConfig.add.passAnonymousToken -ne $passAnonymousToken) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testpassAnonymousTokenConfig'] -f $Name) break } # Check logonType if ($PoolConfig.add.processModel.logonType -ne $logonType) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testlogonTypeConfig'] -f $Name) break } # Check manualGroupMembership if ($PoolConfig.add.processModel.manualGroupMembership -ne $manualGroupMembership) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testmanualGroupMembershipConfig'] -f $Name) break } # Check idleTimeout if ($PoolConfig.add.processModel.idleTimeout -ne $idleTimeout) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testidleTimeoutConfig'] -f $Name) break } # Check maxProcesses if ($PoolConfig.add.processModel.maxProcesses -ne $maxProcesses) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testmaxProcessesConfig'] -f $Name) break } #Check shutdownTimeLimit if ($PoolConfig.add.processModel.shutdownTimeLimit -ne $shutdownTimeLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testshutdownTimeLimitConfig'] -f $Name) break } # Check startupTimeLimit if ($PoolConfig.add.processModel.startupTimeLimit -ne $startupTimeLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['teststartupTimeLimitConfig'] -f $Name) break } # Check pingingEnabled if ($PoolConfig.add.processModel.pingingEnabled -ne $pingingEnabled) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testpingingEnabledConfig'] -f $Name) break } # Check pingInterval if ($PoolConfig.add.processModel.pingInterval -ne $pingInterval) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testpingIntervalConfig'] -f $Name) break } # Check pingResponseTime if ($PoolConfig.add.processModel.pingResponseTime -ne $pingResponseTime) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testpingResponseTimeConfig'] -f $Name) break } # Check disallowOverlappingRotation if ($PoolConfig.add.recycling.disallowOverlappingRotation -ne $disallowOverlappingRotation) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['testdisallowOverlappingRotationConfig'] -f $Name) break } # Check disallowRotationOnConfigChange if ($PoolConfig.add.recycling.disallowRotationOnConfigChange -ne $disallowRotationOnConfigChange) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestdisallowRotationOnConfigChangeConfig'] -f $Name) break } # Check logEventOnRecycle if ($PoolConfig.add.recycling.logEventOnRecycle -ne $logEventOnRecycle) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestlogEventOnRecycleConfig'] -f $Name) break } # Check restartMemoryLimit if ($PoolConfig.add.recycling.periodicRestart.memory -ne $restartMemoryLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrestartMemoryLimitConfig'] -f $Name) break } # Check restartPrivateMemoryLimit if ($PoolConfig.add.recycling.periodicRestart.privateMemory -ne $restartPrivateMemoryLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrestartPrivateMemoryLimitConfig'] -f $Name) break } # Check restartRequestsLimit if ($PoolConfig.add.recycling.periodicRestart.requests -ne $restartRequestsLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrestartRequestsLimitConfig'] -f $Name) break } # Check restartTimeLimit if ($PoolConfig.add.recycling.periodicRestart.time -ne $restartTimeLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrestartTimeLimitConfig'] -f $Name) break } # Check restartSchedule $periodicRestartValue = $PoolConfig.add.recycling.periodicRestart.schedule.add.value if (( $periodicRestartValue -ne $null) ` -and ((Compare-Object ` -ReferenceObject $restartSchedule ` -DifferenceObject $periodicRestartValue) -ne $null)) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrestartTimeLimitConfig'] -f $Name) break } if (($periodicRestartValue -eq $null) -and ($restartSchedule -ne $null)) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrestartTimeLimitConfig'] -f $Name) break } # Check loadBalancerCapabilities if ($PoolConfig.add.failure.loadBalancerCapabilities -ne $loadBalancerCapabilities) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestloadBalancerCapabilitiesConfig'] -f $Name) break } # Check orphanWorkerProcess if ($PoolConfig.add.failure.orphanWorkerProcess -ne $orphanWorkerProcess) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestorphanWorkerProcessConfig'] -f $Name) break } # Check orphanActionExe if ($PoolConfig.add.failure.orphanActionExe -ne $orphanActionExe) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestorphanActionExeConfig'] -f $Name) break } # Check orphanActionParams if ($PoolConfig.add.failure.orphanActionParams -ne $orphanActionParams) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestorphanActionParamsConfig'] -f $Name) break } # Check rapidFailProtection if ($PoolConfig.add.failure.rapidFailProtection -ne $rapidFailProtection) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrapidFailProtectionConfig'] -f $Name) break } # Check rapidFailProtectionInterval if ($PoolConfig.add.failure.rapidFailProtectionInterval -ne $rapidFailProtectionInterval) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrapidFailProtectionIntervalConfig'] -f $Name) break } # Check rapidFailProtectionMaxCrashes if ($PoolConfig.add.failure.rapidFailProtectionMaxCrashes -ne $rapidFailProtectionMaxCrashes) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestrapidFailProtectionMaxCrashesConfig'] -f $Name) break } # Check autoShutdownExe if ($PoolConfig.add.failure.autoShutdownExe -ne $autoShutdownExe) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestautoShutdownExeConfig'] -f $Name) break } # Check autoShutdownParams if ($PoolConfig.add.failure.autoShutdownParams -ne $autoShutdownParams) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestautoShutdownParamsConfig'] -f $Name) break } # Check cpuLimit if ($PoolConfig.add.cpu.limit -ne $cpuLimit) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestcpuLimitConfig'] -f $Name) break } # Check cpuAction if ($PoolConfig.add.cpu.action -ne $cpuAction) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestcpuActionConfig'] -f $Name) break } # Check cpuResetInterval if ($PoolConfig.add.cpu.resetInterval -ne $cpuResetInterval) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestcpuResetIntervalConfig'] -f $Name) break } # Check cpuSmpAffinitized if ($PoolConfig.add.cpu.smpAffinitized -ne $cpuSmpAffinitized) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestcpuSmpAffinitizedConfig'] -f $Name) break } # Check cpuSmpProcessorAffinityMask if ($PoolConfig.add.cpu.smpProcessorAffinityMask -ne $cpuSmpProcessorAffinityMask) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestcpuSmpProcessorAffinityMaskConfig'] -f $Name) break } # Check cpuSmpProcessorAffinityMask2 if ($PoolConfig.add.cpu.smpProcessorAffinityMask2 -ne $cpuSmpProcessorAffinityMask2) { $DesiredConfigurationMatch = $false Write-Verbose -Message $($LocalizedData['TestcpuSmpProcessorAffinityMask2Config'] -f $Name) break } } $Stop = $false } While($Stop) return $DesiredConfigurationMatch } function Invoke-AppCmd { param ( [string[]] $Arguments, [string] $Path = "$env:SystemRoot\system32\inetsrv\appcmd.exe" ) if (Test-Path $Path) { & $Path $Arguments } else { throw "$Path does not exist" } } |