I am trying to write a script to check health of my web application's health status. Forexample if I couldn't get message in 10 seconds I have to recycle my apppool by using Powershell.Or except 200-ok codes, my app pool should recycled.
Please look at below code and ERROR:
# Load IIS module:
Import-Module WebAdministration
while ($true) {
write-host 'Runnig For Check app.xxx.com ...'
# First we create the request.
$HTTP_Request = [System.Net.WebRequest]::Create('https://app.xxx.com/')
Try
{
# We then get a response from the site.
$HTTP_Response = $HTTP_Request.GetResponse()
# We then get the HTTP code as an integer.
$HTTP_Status = [int]$HTTP_Response.StatusCode
If ($HTTP_Status -eq 200) {
Write-Host "Site is OK!"
}
Else {
Write-Host "The Site may be down, please check!"
Restart-WebAppPool -Name "app.xxx.com"
}
}
Catch
{
Stop-WebAppPool -Name "app.xxx.com"
Restart-WebAppPool -Name "app.xxx.com"
}
# Finally, we clean up the http request by closing it.
$HTTP_Response.Close()
Start-Sleep -Seconds 120
}
Error:
Restart-WebAppPool : You have to start stopped object before
restarting it. At C:\Scripts\CheckHealthHaydigo.ps1:25 char:6
+ Restart-WebAppPool -Name "app.xxx.com"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Restart-WebAppPool], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.IIs.PowerShell.Provider.RestartAppPoolCommand
It seems like you should check the status of the app pool before trying to restart it.
if ((Get-WebAppPoolState -Name "app.xxx.com").Value -eq "Stopped") {
Start-WebAppPool -Name "app.xxx.com"
}
else {
Restart-WebAppPool -Name "app.xxx.com"
}
Related
First post! I apologize in advance for formatting. I'm just getting familiar with PowerShell and I'm wanting to Stop a service first, restart another service, and start the initial service. Before moving onto the next next service, I want to make sure that the service has stopped before proceeding.
I'm using this function that was mentioned here and tried to tailor it for my code.
Workflow Goal:
Stop Service A
Restart Service B
Start Service A
Code:
#Stops Service A and validates its in "Stopped" status
Get-Service 'ServiceNameA' -ComputerName 'ExampleServerA' | Stop-Service -force -PassThru
function WaitUntilServices1($searchString, $status)
{
# Get all services where DisplayName matches $searchString and loop through each of them.
foreach($service in (Get-Service -DisplayName $searchString))
{
# Wait for the service to reach the $status or a maximum of 30 seconds
$service.WaitForStatus($status, '00:00:30')
}
}
WaitUntilServices1 "ServiceDisplayNameA" "Stopped"
#Restarts Service B and validates its in "Running" status
Get-Service 'ServiceNameB' -ComputerName 'ExampleServerB' | Restart-Service -force -PassThru
function WaitUntilServices2($searchString, $status)
{
# Get all services where DisplayName matches $searchString and loop through each of them.
foreach($service in (Get-Service -DisplayName $searchString))
{
# Wait for the service to reach the $status or a maximum of 30 seconds
$service.WaitForStatus($status, '00:00:30')
}
}
WaitUntilServices2 "ServiceDisplayNameB" "Running"
#Start Service A and validates its in "Running" status
Get-Service 'ServiceA' -ComputerName 'ExampleServerA' | Start-Service -force -PassThru
Read-Host -Prompt "Press Enter to exit"
The Code I have above is giving me the following Errors for both of the functions.
Exception calling "WaitForStatus" with "2" argument(s): "Time out has expired and the operation has not been completed." At C:\PowerShell\ScriptExample\ScriptExampleFix.ps1:10 char:9
$service.WaitForStatus($status, '00:00:30')
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : TimeoutException
Then for the very last portion to start the service I'm getting 1 more error:
Start-Service : A parameter cannot be found that matches parameter name 'force'. At C:\PowerShell\ScriptExample\ScriptExampleFix.ps1:32 char:85
+ ... erName 'ServerNameExample' | Start-Service -force -PassTh ...
+ ~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Start-Service], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.StartServiceCommand
Any help would get greatly appreciated :)
In the first statement:
#Stops Service A and validates its in "Stopped" status
Get-Service 'ServiceNameA' -ComputerName 'ExampleServerA' | Stop-Service -force -PassThru
You ask PowerShell to stop ServiceNameA on a remote computer.
You then call WaitUntilServices1 which attempts to wait for a service of the same name on your local computer - which is obviously not gonna stop any time soon because you requested stopping a service on a different computer.
Change the function definition to accept a -ComputerName parameter too and pass that to Get-Service:
function Wait-ServiceStatus {
param(
[string]$Name,
[string]$ComputerName = $('.'),
[System.ServiceProcess.ServiceControllerStatus]$Status
)
foreach($service in Get-Service -Name $Name -ComputerName $ComputerName){
# If any call to WaitForStatus times out and throws, return $false
try { $service.WaitForStatus($Status, '00:00:30') } catch { return $false }
}
# No errors thrown while waiting, all is good, return $true
return $true
}
Now we can do:
# request the remote SCM stop the service
Get-Service 'ServiceNameA' -ComputerName 'ExampleServerA' | Stop-Service -Force
$success = Wait-ServiceStatus -Name 'ServiceNameA' -ComputerName 'ExampleServerA' -Status Stopped
if(-not $success){
# output an error
Write-Error "failed to complete restart cycle, 'ServiceNameA' on 'ExampleServerA' failed to stop in a timely manner"
# return from this script/function for good measure
return
}
# ... if we've reached this point the wait must have been successful, continue with the restart cycle.
Get-Service 'ServiceNameB' -ComputerName 'ExampleServerB' | Restart-Service -force -PassThru
$success = Wait-ServiceStatus -Name 'ServiceNameB' -ComputerName 'ExampleServerB' -Status Running
if(-not $success){
# ... etc.
}
Publish-AzWebApp throws an error when uploading the Source Code for the aplication. The code is the following:
$job = Publish-AzWebApp `
-WebApp $webApp `
-ArchivePath (Join-Path -Path $rootPath -ChildPath $archiveRelativePath) `
-Force `
-AsJob
# # #
# ...code...
# # #
# Later on
$job | Receive-Job -AutoRemoveJob -Wait -WriteJobInResults | ForEach-Object {
if ("AzureLongRunningJob" -eq $_.GetType().BaseType.Name) {
if ("Completed" -eq $_.JobStateInfo.State) {
Write-Log -Message "Published the Source Code for $($webApp.Name) successfully." -Level INFO
}
else {
Write-Log -Message $_.JobStateInfo -Level ERROR
throw $_.JobStateInfo
}
}
}
The error is the following:
Deployment failed with status code ServiceUnavailable
+ CategoryInfo : InvalidResult: (:) [], Exception
+ FullyQualifiedErrorId :
The thing is that between the beginning of the job and the end of the job I am also uploading WebJobs and and also I'm setting the AppSettings from the Configuration Blade.
I also noticed that this happens when I am creating the app then doing this procedure in one go. But if the app exists, the error is less likely to occur. Still it doesn't seem like it is stable. What could I do?
I see below error logs when ever i try to copy items from a path to destination . This PS script task is scheduled under a Jenkins Job. This is messing up things as build fails every time.
Error Logs-
Copy-Item : The process cannot access the file
'\\10.0.1.190\d$\Build\RPC\Fortius.RPC.AmadeusAir\Common.Logging.Core.dll' because it is being used by another process.
At C:\Users\Administrator\AppData\Local\Temp\hudson5254771699639808940.ps1:33 char:1
+ Copy-Item "$ReleaseDir\*" $AmadeusDir -Force -Recurse
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
PS Script-
# force strict - so any variable used before being assigned causes an error
Set-PsDebug -Strict
# force PowerShell to exit with a non-zero code on the first error
$ErrorActionPreference = 'Stop'
# set directories here once, so we can reuse
$AmadeusDir = "\\$env:SERVER\d$\Build\RPC\Fortius.RPC.AmadeusAir"
$ReleaseDir = "C:\Amadeus\BTP\src\Fortius.Amadeus.Air.RPC.Host\bin\Release"
# get directory contents (are you expecting these to return to Jenkins?)
Get-ChildItem "$AmadeusDir\*"
Get-ChildItem "$ReleaseDir\*"
# create the search directory if it doesn't exist
if (-not (Test-Path -Path $AmadeusDir -PathType Container)) { New-Item -Path $AmadeusDir -type directory -Force }
# get the service, but fail gracefully if it doesn't exist
$service = Get-Service -Name AmadeusAirWindowsService -Computername $env:SERVER -ErrorAction SilentlyContinue
# if we have a service, stop and delete it
if($service.Status)
{
sc.exe \\$env:SERVER stop AmadeusAirWindowsService
if ($LASTEXITCODE -ne 0) { throw "error stopping the service: $LASTEXITCODE" }
Write-Host "AmadeusAirWindowsService STOPPED"
sc.exe \\$env:SERVER delete AmadeusAirWindowsService
if ($LASTEXITCODE -ne 0) { throw "error deleting the service: $LASTEXITCODE" }
Write-Host "AmadeusAirWindowsService DELETED"
}
# copy release to search
Copy-Item "$ReleaseDir\*" $AmadeusDir -Force -Recurse
# (re)create the service
sc.exe \\$env:SERVER create AmadeusAirWindowsService start=auto DisplayName="Fortius Amadeus Air RPC Service" binPath= D:\Build\RPC\Fortius.RPC.AmadeusAir\WorldVentures.Fortius.Amadeus.Air.RPC.Host.exe
if ($LASTEXITCODE -ne 0) { throw "error creating the service: $LASTEXITCODE" }
sc.exe \\$env:SERVER description AmadeusAirWindowsService "This service hosts Fortius Amadeus Air RPC service"
if ($LASTEXITCODE -ne 0) { throw "error adding description to service: $LASTEXITCODE" }
sc.exe \\$env:SERVER start AmadeusAirWindowsService
if ($LASTEXITCODE -ne 0) { throw "error starting the service: $LASTEXITCODE" }
Write-Host "AmadeusAirWindowsService STARTED"
As an alternate I am using
xcopy "From" "destination" /k/e/d/Y to do that
You're trying to copy over stuff while the destination still has files in use. Have you checked what is keeping this/these file(s) locked? You already stopped the service I see, did you actually check if that went successfully? Also SysInternals has "handle" and "process explorer" which can both checks what is keeping your file locked.
Lets say there is an application with the name exampleService that should be running on Server1. This code works if it is running. However when it's not running, it crashes.
$application = Get-Process -ComputerName Server1 -Name "exampleService"
I get this crash if the application is not running. Is there a more graceful way of finding out if it's not running (without crashing)
Get-Process : Cannot find a process with the name "exampleService". Verify the process name and call the cmdlet again.
At line:1 char:16
+ $application = Get-Process -ComputerName Server1 -Name "exampleService"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Sampler:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
Also is it possible to launch the application on the Server if it's not running?
The Server is running Windows Server 2012. The PowerShell commands are being run from a Windows 7 64-bit PC.
Look at using -ErrorAction SilentlyContinue to keep that error from displaying. You can use that in an If statement to launch the application if it isn't running.
--Updated to include launching the remote process
If (-NOT (Get-Process -Computername Server1 -name "cmd" -ErrorAction SilentlyContinue)) {
Write-Host "Launch application"
$application = "c:\windows\system32\cmd.exe"
$start = ([wmiclass]"\\Server1\Root\CIMV2:win32_process").Create($application)
}
You could set the ErrorActionto SilentlyContinue (alias for that is -ea 0):
$application = Get-Process -ComputerName Server1 -Name "exampleService" -ea 0
Now you can check $application and start the application if its null.
I only wanted my script to continue on one particular Get-Process error, i.e. process not found. (and I preferred to use a Try/Catch). But I haven't done much powershell and had trouble locating the specific error.
Once I found I could look at FullyQualifiedErrorId and added the following to a general Catch block I located what I was after.
Write-Host ('FullyQualifiedErrorId: ' + $_.FullyQualifiedErrorId);
So as a full example which works for my situation:
Try {
$application = Get-Process -Name "exampleService" -ea Stop #note the -ea Stop is so try catch will fire whatever ErrorAction is configured
} Catch [Microsoft.PowerShell.Commands.ProcessCommandException] {
If ($_.FullyQualifiedErrorId) {
If ($_.FullyQualifiedErrorId -eq "NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand"){
Write-Host "Presume not running. That is OK."; # or you could perform start action here
}
}
else {
throw #rethrow other processcommandexceptions
}
} Catch {
# Log details so we can refine catch block above if needed
Write-Host ('Exception Name:' + $_.Exception.GetType().fullname); # what to put in the catch's square brackets
If ($_.FullyQualifiedErrorId) {
Write-Host ('FullyQualifiedErrorId: ' + $_.FullyQualifiedErrorId); #what specific ID to check for
}
throw #rethrow so script stops
}
Attempting to run the follow script for a reboot I get the following error,
"Send-MailMessage : Cannot validate argument on parameter 'Body'. The argument is null or empty. Supply an arg
that is not null or empty and then try the command again.
At line:8 char:30
+ Send-MailMessage #messageParameters -BodyAsHtml
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage"
Any help would be great!
Thanks
Cody
Restart-Computer -ComputerName nocconverter1 -Wait -For Wmi
$server = 'XXX'
ping -n 2 $server >$null
Function Server_Status_Check {
if($lastexitcode -eq 0) {
write-host "$server is ONLINE"
} else {
write-host "$server is OFFLINE/UNREACHABLE"
}
}
$messageParameters = #{
Subject = "Result: Reboot report for WebPeriop - $((Get-Date).ToShortDateString())"
Body = Server_Status_Check | out-string
From = "XXXX"
To = "XXXXX"
SmtpServer = "exmbx6"
}
Send-MailMessage #messageParameters -BodyAsHtml
Write-Host writes directly to the display. It doesn't write to stdout out therefore your Server_Status_Check function outputs nothing. Change it to:
Function Server_Status_Check {
if($lastexitcode -eq 0) {
"$server is ONLINE"
}
else {
"$server is OFFLINE/UNREACHABLE"
}
}