Skip to content

Instantly share code, notes, and snippets.

@aivascu
Created May 11, 2015 09:10
Show Gist options
  • Save aivascu/43e1c5bb32df555fe289 to your computer and use it in GitHub Desktop.
Save aivascu/43e1c5bb32df555fe289 to your computer and use it in GitHub Desktop.
Installs a windows service on a local/remote machine
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$ServiceName = $(throw "Service name is required."),
[Parameter(Mandatory = $true, Position = 1)]
[string]$BinPath = $(throw "The service's binary path is required."),
[Parameter(Mandatory = $true, Position = 1)]
[string]$ServiceDisplayName = $(throw "The service's display name is required."),
[Parameter(Mandatory = $true, Position = 1)]
[string]$ServiceDescription = $(throw "The service's description is required."),
[Parameter(Mandatory = $false)]
[string]$DeploymentServer
)
function Install-RemoteService(
[string]$serviceName = $(throw "serviceName is required"),
[string]$targetServer = $(throw "targetServer is required"),
[string]$displayName = $(throw "displayName is required"),
[string]$physicalPath = $(throw "physicalPath is required"),
[string]$userName = $(throw "userName is required"),
[string]$password = "",
[string]$startMode = "Automatic",
[string]$description = "",
[bool]$interactWithDesktop = $false
)
{
# todo: cleanup this section
$serviceType = 16 # OwnProcess
$serviceErrorControl = 1 # UserNotified
$loadOrderGroup = $null
$loadOrderGroupDepend = $null
$dependencies = $null
# description?
$params = `
$serviceName, `
$displayName, `
$physicalPath, `
$serviceType, `
$serviceErrorControl, `
$startMode, `
$interactWithDesktop, `
$userName, `
$password, `
$loadOrderGroup, `
$loadOrderGroupDepend, `
$dependencies `
$scope = new-object System.Management.ManagementScope("\\$targetServer\root\cimv2", (new-object System.Management.ConnectionOptions))
"Connecting to $targetServer ..."
$scope.Connect()
$mgt = new-object System.Management.ManagementClass($scope, (new-object System.Management.ManagementPath("Win32_Service")), (new-object System.Management.ObjectGetOptions))
$op = "service $serviceName ($physicalPath) on $targetServer"
"Installing $op ..."
$result = $mgt.InvokeMethod("Create", $params)
Test-ServiceResult -operation "Install $op" -result $result
"Installed $op !"
"Setting $serviceName description to '$description'"
Set-Service -ComputerName $targetServer -Name $serviceName -Description $description
"Service install complete!"
}
function Test-ServiceResult(
[string]$operation = $(throw "operation is required"),
[object]$result = $(throw "result is required"),
[switch]$continueOnError = $false)
{
$retVal = -1
if ($result.GetType().Name -eq "UInt32") { $retVal = $result } else {$retVal = $result.ReturnValue}
if ($retVal -eq 0) {return}
$errorcode = 'Success,Not Supported,Access Denied,Dependent Services Running,Invalid Service Control'
$errorcode += ',Service Cannot Accept Control, Service Not Active, Service Request Timeout'
$errorcode += ',Unknown Failure, Path Not Found, Service Already Running, Service Database Locked'
$errorcode += ',Service Dependency Deleted, Service Dependency Failure, Service Disabled'
$errorcode += ',Service Logon Failure, Service Marked for Deletion, Service No Thread'
$errorcode += ',Status Circular Dependency, Status Duplicate Name, Status Invalid Name'
$errorcode += ',Status Invalid Parameter, Status Invalid Service Account, Status Service Exists'
$errorcode += ',Service Already Paused'
$desc = $errorcode.Split(',')[$retVal]
$msg = ("{0} failed with code {1}:{2}" -f $operation, $retVal, $desc)
if (!$continueOnError) { Write-Error $msg } else { Write-Warning $msg }
}
$service = $null
if([string]::IsNullOrWhiteSpace($DeploymentServer))
{
New-Service -Name $ServiceName -BinaryPathName $BinPath -DisplayName $ServiceDisplayName -Description $ServiceDescription -StartupType Automatic
$service = Get-Service -Name $ServiceName
}
else
{
Install-RemoteService -serviceName $ServiceName -targetServer $DeploymentServer -displayName $ServiceDisplayName -physicalPath $BinPath -userName "LocalSystem" -description $ServiceDescription
$service = Get-Service -ComputerName $DeploymentServer -Name $ServiceName
}
if($service)
{
Start-Service $service
Write-Host "Waiting for the service to start..."
Start-Sleep -s 5
if($service.Status -eq "Running")
{
Write-Output "The service is now running!"
}
else
{
Write-Error "The service could not be started!"
}
}
else
{
Write-Error "The service could not be created!"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment