Octopus.Script exported 2017-06-20 by dunedinsoftware belongs to ‘Windows’ category.
Starts/stops one or more services asynchronously, and then waits for them to align to the specified state
Parameters
When steps based on the template are included in a project’s deployment process, the parameters below can be set.
Services to align
Services
A comma delimited list of services or wildcards (eg. “Sky”) to align
Services to ignore
ServicesToIgnore
A comma delimited list of services or wildcards (eg. “Sky”) to ignore
Desired state
DesiredState
The desired state of the service/s. Specify either “Started” or “Stopped”
Timeout in seconds
TimeoutSeconds = 300
The number of seconds to wait for the service/s to align before timing out and throwing an exception
Script body
Steps based on this template will execute the following PowerShell script.
$ServicesToManage = $OctopusParameters['Services']
$ServicesToIgnore = $OctopusParameters['ServicesToIgnore']
$TimeoutSeconds = $OctopusParameters['TimeoutSeconds']
$DesiredState = $OctopusParameters['DesiredState']
# Gather information about the list of services
$services_status = @{}
# For each "service to manage" or wildcard specified ...
$ServicesToManage -split "," |% `
{
$service = $_
# ... retrieve all the services that match that name or wildcard ...
$service_states = Get-Service |? { $_.Name -match $service }
# ... and add them into an array; we use a key/value array so that services only get added to the array once, even if they are
# matched by multiple wildcard specifications
$service_states |% { $services_status[$_.Name] = $_.Status }
}
# For each "service to ignore" or wildcard specified ...
$ServicesToIgnore -split "," |% `
{
$service = $_
# Copy the keys within services_status, since we will need to change services_status as we enumerate them
$keys = @()
$services_status.Keys |% { $keys += $_ }
$keys |% `
{
$key = $_
if ($key -match $service -and $service -match "[a-z]+")
{
$services_status.Remove($_)
}
}
}
Write-Host "Matched the following set of services, along with their current status:"
$services_status
# Now act as required to bring the services to the desired configuration state
[DateTime]$startTime = [DateTime]::Now
# State to pass to sc
$state_type = if ($DesiredState -match "Stopped") { "stop" } else { "start" }
$unaligned_services = ($services_status.Keys |? { $services_status[$_] -notmatch $DesiredState })
# Attempt to align the remaining services
$unaligned_services |% `
{
Write-Host "Attempting to $state_type service: $_"
Start-Process -FilePath "cmd" -ArgumentList "/c sc.exe $state_type `"$_`""
}
while ($startTime.AddSeconds($TimeoutSeconds) -gt [DateTime]::Now)
{
# Attempt to align the remaining services
$unaligned_services |% `
{
Write-Host "Attempting to $state_type service: $_"
$services_status[$_] = Get-Service $_ | Select-Object -Property "Status"
}
$unaligned_services = ($services_status.Keys |? { $services_status[$_] -notmatch $DesiredState })
Write-Host "$([DateTime]::Now): $($unaligned_services.Count) services of $($services_status.Count) not yet at status: $DesiredState"
if ($unaligned_services.Count -eq 0)
{
Write-Host "All services now at desired state; exiting"
exit 0
}
# Pause for a second
[System.Threading.Thread]::Sleep(1000)
}
throw "Error: not all services reached the desired state within the specified timeframe: $unaligned_services"
Provided under the Apache License version 2.0.
To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.
{
"Id": "1cdf63ce-50c8-45a8-cce2-f6ca2d6d617b",
"Name": "DSC Windows Service",
"Description": "Starts/stops one or more services asynchronously, and then waits for them to align to the specified state",
"Version": 15,
"ExportedAt": "2017-06-20T14:35:09.389Z",
"ActionType": "Octopus.Script",
"Author": "dunedinsoftware",
"Parameters": [
{
"Name": "Services",
"Label": "Services to align",
"HelpText": "A comma delimited list of services or wildcards (eg. \"Sky\") to align",
"DefaultValue": null,
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Name": "ServicesToIgnore",
"Label": "Services to ignore",
"HelpText": "A comma delimited list of services or wildcards (eg. \"Sky\") to ignore",
"DefaultValue": null,
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Name": "DesiredState",
"Label": "Desired state",
"HelpText": "The desired state of the service/s. Specify either \"Started\" or \"Stopped\"",
"DefaultValue": null,
"DisplaySettings": {
"Octopus.ControlType": "Select",
"Octopus.SelectOptions": "Running|Started\nStopped|Stopped"
}
},
{
"Name": "TimeoutSeconds",
"Label": "Timeout in seconds",
"HelpText": "The number of seconds to wait for the service/s to align before timing out and throwing an exception",
"DefaultValue": "300",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
}
],
"Properties": {
"Octopus.Action.Script.Syntax": "PowerShell",
"Octopus.Action.Script.ScriptBody": "\n $ServicesToManage = $OctopusParameters['Services']\n $ServicesToIgnore = $OctopusParameters['ServicesToIgnore']\n $TimeoutSeconds = $OctopusParameters['TimeoutSeconds']\n $DesiredState = $OctopusParameters['DesiredState']\n\n # Gather information about the list of services\n $services_status = @{}\n\n # For each \"service to manage\" or wildcard specified ...\n $ServicesToManage -split \",\" |% `\n {\n $service = $_\n \n # ... retrieve all the services that match that name or wildcard ...\n $service_states = Get-Service |? { $_.Name -match $service }\n \n # ... and add them into an array; we use a key/value array so that services only get added to the array once, even if they are\n # matched by multiple wildcard specifications\n $service_states |% { $services_status[$_.Name] = $_.Status }\n }\n \n # For each \"service to ignore\" or wildcard specified ...\n $ServicesToIgnore -split \",\" |% `\n {\n $service = $_\n \n # Copy the keys within services_status, since we will need to change services_status as we enumerate them\n $keys = @()\n $services_status.Keys |% { $keys += $_ }\n \n $keys |% `\n {\n $key = $_\n \n if ($key -match $service -and $service -match \"[a-z]+\")\n {\n $services_status.Remove($_)\n }\n }\n }\n\n Write-Host \"Matched the following set of services, along with their current status:\"\n $services_status\n\n # Now act as required to bring the services to the desired configuration state\n [DateTime]$startTime = [DateTime]::Now\n \n # State to pass to sc\n $state_type = if ($DesiredState -match \"Stopped\") { \"stop\" } else { \"start\" }\n\n\t$unaligned_services = ($services_status.Keys |? { $services_status[$_] -notmatch $DesiredState })\n\t# Attempt to align the remaining services\n\t$unaligned_services |% `\n\t{ \n\t\tWrite-Host \"Attempting to $state_type service: $_\"\n\t\tStart-Process -FilePath \"cmd\" -ArgumentList \"/c sc.exe $state_type `\"$_`\"\"\n\t}\t\n \n while ($startTime.AddSeconds($TimeoutSeconds) -gt [DateTime]::Now)\n {\n\t\t# Attempt to align the remaining services\n\t\t$unaligned_services |% `\n\t\t{ \n\t\t\tWrite-Host \"Attempting to $state_type service: $_\"\n\t\t\t$services_status[$_] = Get-Service $_ | Select-Object -Property \"Status\"\n\t\t}\t\n\t\t$unaligned_services = ($services_status.Keys |? { $services_status[$_] -notmatch $DesiredState })\n\t\tWrite-Host \"$([DateTime]::Now): $($unaligned_services.Count) services of $($services_status.Count) not yet at status: $DesiredState\"\n\t\t\n if ($unaligned_services.Count -eq 0)\n {\n Write-Host \"All services now at desired state; exiting\"\n exit 0\n }\n\n \n # Pause for a second\n [System.Threading.Thread]::Sleep(1000)\n }\n\n throw \"Error: not all services reached the desired state within the specified timeframe: $unaligned_services\"\n\n\n"
},
"Category": "Windows",
"HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/dsc-windows-service.json",
"Website": "/step-templates/1cdf63ce-50c8-45a8-cce2-f6ca2d6d617b",
"Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF////Da3qSsLvhtb0wur6O7zuWcfxldv2aMzyK7ftpOD3s+X48Pr+0fD7d9HzHLLr4fX8xD/OcwAAAaNJREFUeNrs3cFygjAUQFECWott1f//2sJoW6kIKEzNs+euXOmcmSSGDa8oJEmSJEmSJGmsj1W1K9cpsGD1Vr2WdToVEPC+2lYvZfpVrEW0qZpF1F+MRdRugzoNlvkiarfBPk0pT8GhWUSX2yASpDlLr2+DEJBmEY1ug6whx7N0n2b30G1QlmmxHsRYp6X76yvF9vg5RYQczq8UVURI35UiFmTgShED0p6lI1eKzCHTrxS5Qk6PZ9PLDtJ9PIsJmXWlyAky6/dAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQMJCyjltF/iO3gpJUpD8s4OAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8T8itwwKyhbTdMr4ha8hXUwZqhICcOgyNOIkE+V5wo4MSgr1u/fp7poO+AL8K/gL8yw0UeyRB34m9iQ/pVD8L5JYTO3NI58R+AsiEEzsW5OfE3sUe/zRwYkeGnG2g2CPS7rhjF4GKP0ZwyoldxK37kFqEL/7wU0mSJEmSJOmJ+xRgAHxZTCXGdZkfAAAAAElFTkSuQmCC",
"$Meta": {
"Type": "ActionTemplate"
}
}
Page updated on Tuesday, June 20, 2017