Scripts/Reskit9/All Resources/xExchange/DSCResources/MSFT_xExchJetstress/MSFT_xExchJetstress.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [ValidateSet("Performance","Stress","DatabaseBackup","SoftRecovery")] [System.String] $Type, [parameter(Mandatory = $true)] [System.String] $JetstressPath, [parameter(Mandatory = $true)] [System.String] $JetstressParams, [System.UInt32] $MaxWaitMinutes = 4320 ) #Load helper module Import-Module "$((Get-Item -LiteralPath "$($PSScriptRoot)").Parent.Parent.FullName)\Misc\xExchangeCommon.psm1" -Verbose:0 LogFunctionEntry -Parameters @{"JetstressPath" = $JetstressPath; "JetstressParams" = $JetstressParams} -VerbosePreference $VerbosePreference $returnValue = @{ Type = $Type JetstressPath = $JetstressPath JetstressParams = $JetstressParams MaxWaitMinutes = $MaxWaitMinutes } $returnValue } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [ValidateSet("Performance","Stress","DatabaseBackup","SoftRecovery")] [System.String] $Type, [parameter(Mandatory = $true)] [System.String] $JetstressPath, [parameter(Mandatory = $true)] [System.String] $JetstressParams, [System.UInt32] $MaxWaitMinutes = 4320 ) #Load helper module Import-Module "$((Get-Item -LiteralPath "$($PSScriptRoot)").Parent.Parent.FullName)\Misc\xExchangeCommon.psm1" -Verbose:0 LogFunctionEntry -Parameters @{"JetstressPath" = $JetstressPath; "JetstressParams" = $JetstressParams} -VerbosePreference $VerbosePreference $jetstressRunning = IsJetstressRunning $jetstressSuccessful = JetstressTestSuccessful @PSBoundParameters if ($jetstressSuccessful -eq $false -and (Get-ChildItem -LiteralPath "$($JetstressPath)" | where {$_.Name -like "$($Type)*.html"}) -ne $null) { throw "Jetstress was previously executed and resulted in a failed run. Clean up any $($Type)*.html files in the Jetstress install directory before trying to run this resource again." } if ($jetstressRunning -eq $false) #Jetstress isn't running. Kick it off { $initializingESE = $false #If the ESE counters haven't been registered for Perfmon, Jetstress is going to need to initialize ESE and restart the process. if ((Test-Path -LiteralPath "$($env:SystemRoot)\Inf\ESE\eseperf.ini") -eq $false) { $initializingESE = $true } #Create and start the Jetstress scheduled task StartJetstress @PSBoundParameters #Give an additional 60 seconds if ESE counters were just initialized. if ($initializingESE -eq $true) { Write-Verbose "Jetstress has never initialized performance counters for ESE. Waiting a full 60 seconds for this to occurr" Start-Sleep -Seconds 60 $jetstressRunning = IsJetstressRunning #I've found that Jetstress doesn't always restart after loading ESE when running as local system in a scheduled task in the background #If Jetstress isn't running at this point, but the perf counters were registered, try to start Jetstress one more time just to make sure this didn't happen. if ($jetstressRunning -eq $false) { if ((Test-Path -LiteralPath "$($env:SystemRoot)\Inf\ESE\eseperf.ini") -eq $true) { Write-Verbose "ESE performance counters were registered, but JetstressCmd.exe is not currently running. Attempting to start it one more time" StartJetstress @PSBoundParameters } else { throw "Jetstress failed to register MSExchange Database performance counters" } } } else { $jetstressRunning = IsJetstressRunning } #Wait up to a minute for Jetstress to start. If it hasn't started by then, something went wrong $checkMaxTime = [DateTime]::Now.AddMinutes(1) while ($jetstressRunning -eq $false -and $checkMaxTime -gt [DateTime]::Now) { $jetstressRunning = IsJetstressRunning if ($jetstressRunning -eq $false) { Start-Sleep -Seconds 1 } } if ($jetstressRunning -eq $false) { throw "Waited 60 seconds after launching the Jetstress scheduled task, but failed to detect that JetstressCmd.exe is running" } } #If we made it here, Jetstress is running. Wait for it to complete for $MaxWaitMinutes minutes $checkMaxTime = [DateTime]::Now.AddMinutes($MaxWaitMinutes) while ($jetstressRunning -eq $true -and $checkMaxTime -gt [DateTime]::Now) { Write-Verbose "Jetstress is still running at '$([DateTime]::Now)'." #Wait for 5 minutes before logging to the screen again, but actually check every 5 seconds whether Jetstress has completed. for ($i = 0; $i -lt 300 -and $jetstressRunning -eq $true; $i += 5) { $jetstressRunning = IsJetstressRunning if ($jetstressRunning -eq $true) { Start-Sleep -Seconds 5 } } } #Check the final status on the Jetstress run if ($jetstressRunning -eq $false) { Write-Verbose "Jetstress testing finished at '$([DateTime]::Now)'." $testSuccessful = JetstressTestSuccessful @PSBoundParameters if ($testSuccessful -eq $false) { throw "Jetstress finished running, but the test did not complete successfully" } else { Write-Verbose "Jetstress finished, and the configured test passed" } } else { throw "Jetstress is still running after waiting $($MaxWaitMinutes) minutes" } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [ValidateSet("Performance","Stress","DatabaseBackup","SoftRecovery")] [System.String] $Type, [parameter(Mandatory = $true)] [System.String] $JetstressPath, [parameter(Mandatory = $true)] [System.String] $JetstressParams, [System.UInt32] $MaxWaitMinutes = 4320 ) #Load helper module Import-Module "$((Get-Item -LiteralPath "$($PSScriptRoot)").Parent.Parent.FullName)\Misc\xExchangeCommon.psm1" -Verbose:0 LogFunctionEntry -Parameters @{"JetstressPath" = $JetstressPath; "JetstressParams" = $JetstressParams} -VerbosePreference $VerbosePreference $jetstressRunning = IsJetstressRunning -MaximumWaitSeconds 1 if ($jetstressRunning -eq $true) { return $false } else { $jetstressSuccessful = JetstressTestSuccessful @PSBoundParameters return $jetstressSuccessful } } #Checks whether the JetstressCmd.exe process is currently running function IsJetstressRunning { $process = Get-Process -Name JetstressCmd -ErrorAction SilentlyContinue return ($process -ne $null) } #Used to create a scheduled task which will initiate the Jetstress run function StartJetstress { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [ValidateSet("Performance","Stress","DatabaseBackup","SoftRecovery")] [System.String] $Type, [parameter(Mandatory = $true)] [System.String] $JetstressPath, [parameter(Mandatory = $true)] [System.String] $JetstressParams, [System.UInt32] $MaxWaitMinutes = 4320 ) Import-Module "$((Get-Item -LiteralPath "$($PSScriptRoot)").Parent.Parent.FullName)\Misc\xExchangeCommon.psm1" -Verbose:0 $fullPath = Join-Path -Path "$($JetstressPath)" -ChildPath "JetstressCmd.exe" StartScheduledTask -Path "$($fullPath)" -Arguments "$($JetstressParams)" -WorkingDirectory "$($JetstressPath)" -TaskName "Jetstress" -VerbosePreference $VerbosePreference } #Looks in the latest Type*.html file to determine whether the last Jetstress run passed function JetstressTestSuccessful { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [ValidateSet("Performance","Stress","DatabaseBackup","SoftRecovery")] [System.String] $Type, [parameter(Mandatory = $true)] [System.String] $JetstressPath, [parameter(Mandatory = $true)] [System.String] $JetstressParams, [System.UInt32] $MaxWaitMinutes = 4320 ) $testSuccessful = $false $outputFiles = Get-ChildItem -LiteralPath "$($JetstressPath)" | where {$_.Name -like "$($Type)*.html"} if ($outputFiles -ne $null -and $outputFiles.Count -ge 1) { $outputFiles = $outputFiles | Sort-Object -Property LastWriteTime -Descending $latest = $outputFiles[0] $content = Get-Content -LiteralPath "$($latest.FullName)" $foundResults = $false for ($i = 0; $i -lt $content.Length -and $foundResults -eq $false; $i++) { if ($content[$i].Contains("<td class=`"grid_row_header`">Overall Test Result</td>")) { $resultStart = $content[$i + 1].IndexOf('>') + 1 $resultEnd = $content[$i + 1].LastIndexOf('<') $result = $content[$i + 1].Substring($resultStart, $resultEnd - $resultStart) $foundResults = $true Write-Verbose "File $($latest.FullName)'' has an 'Overall Test Result' of '$($result)'" if ($result -like "Pass") { $testSuccessful = $true } } } if ($foundResults -eq $false) { Write-Verbose "Unable to find 'Overall Test Result' in file '$($latest.FullName)'" } } else { Write-Verbose "Unable to find any files matching '$($Type)*.html' in folder '$($JetstressPath)'" } return $testSuccessful } Export-ModuleMember -Function *-TargetResource |