@ -3,6 +3,7 @@
# Copyright: (c) 2015, George Frank <george@georgefrank.net>
# Copyright: (c) 2015, George Frank <george@georgefrank.net>
# Copyright: (c) 2015, Adam Keech <akeech@chathamfinancial.com>
# Copyright: (c) 2015, Adam Keech <akeech@chathamfinancial.com>
# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de>
# Copyright: (c) 2015, Hans-Joachim Kliemeck <git@kliemeck.de>
# Copyright: (c) 2019, Kevin Subileau (@ksubileau)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Requires -Module Ansible.ModuleUtils.Legacy
# Requires -Module Ansible.ModuleUtils.Legacy
@ -11,671 +12,472 @@
$ErrorActionPreference = " Stop "
$ErrorActionPreference = " Stop "
$params = Parse-Args $args
$start_modes_map = @ {
" auto " = " SERVICE_AUTO_START "
$result = @ {
" delayed " = " SERVICE_DELAYED_AUTO_START "
changed = $false
" manual " = " SERVICE_DEMAND_START "
" disabled " = " SERVICE_DISABLED "
}
}
$params = Parse-Args -arguments $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name " _ansible_check_mode " -type " bool " -default $false
$diff_mode = Get-AnsibleParam -obj $params -name " _ansible_diff " -type " bool " -default $false
$name = Get-AnsibleParam -obj $params -name " name " -type " str " -failifempty $true
$name = Get-AnsibleParam -obj $params -name " name " -type " str " -failifempty $true
$state = Get-AnsibleParam -obj $params -name " state " -type " str " -default " present " -validateset " present " , " absent " , " started " , " stopped " , " restarted " -resultobj $result
$state = Get-AnsibleParam -obj $params -name " state " -type " str " -default " present " -validateset " present " , " absent " , " started " , " stopped " , " restarted " -resultobj $result
$display_name = Get-AnsibleParam -obj $params -name 'display_name' -type 'str'
$description = Get-AnsibleParam -obj $params -name 'description' -type 'str'
$application = Get-AnsibleParam -obj $params -name " application " -type " str "
$application = Get-AnsibleParam -obj $params -name " application " -type " path "
$appDirectory = Get-AnsibleParam -obj $params -name " working_directory " -aliases " app_directory " , " chdir " -type " path "
$appParameters = Get-AnsibleParam -obj $params -name " app_parameters "
$appParameters = Get-AnsibleParam -obj $params -name " app_parameters "
$appParametersFree = Get-AnsibleParam -obj $params -name " app_parameters_free_form " -type " str "
$appArguments = Get-AnsibleParam -obj $params -name " arguments " -aliases " app_parameters_free_form "
$startMode = Get-AnsibleParam -obj $params -name " start_mode " -type " str " -default " auto " -validateset " auto " , " delayed " , " manual " , " disabled " -resultobj $result
$stdoutFile = Get-AnsibleParam -obj $params -name " stdout_file " -type " str "
$stdoutFile = Get-AnsibleParam -obj $params -name " stdout_file " -type " path "
$stderrFile = Get-AnsibleParam -obj $params -name " stderr_file " -type " str "
$stderrFile = Get-AnsibleParam -obj $params -name " stderr_file " -type " path "
$dependencies = Get-AnsibleParam -obj $params -name " dependencies " -type " list "
$executable = Get-AnsibleParam -obj $params -name " executable " -type " path " -default " nssm.exe "
# Deprecated options since 2.8. Remove in 2.12
$startMode = Get-AnsibleParam -obj $params -name " start_mode " -type " str " -default " auto " -validateset $start_modes_map . Keys -resultobj $result
$dependencies = Get-AnsibleParam -obj $params -name " dependencies " -type " list "
$user = Get-AnsibleParam -obj $params -name " user " -type " str "
$user = Get-AnsibleParam -obj $params -name " user " -type " str "
$password = Get-AnsibleParam -obj $params -name " password " -type " str "
$password = Get-AnsibleParam -obj $params -name " password " -type " str "
if ( ( $appParameters -ne $null ) -and ( $appParametersFree -ne $null ) )
$result = @ {
{
changed = $false
Fail-Json $result " Use either app_parameters or app_parameteres_free_form, but not both "
}
if ( ( $appParameters -ne $null ) -and ( $appParameters -isnot [ string ] ) ) {
Fail-Json -obj $result -message " The app_parameters parameter must be a string representing a dictionary. "
}
}
$diff_text = $null
Function Nssm-Invoke
function Invoke-NssmCommand {
{
[ CmdletBinding ( ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true )]
[ Parameter ( Mandatory = $true ,ValueFromRemainingArguments = $true )]
[ string ] $cmd
[ string []] $arguments
)
)
$nssm_result = Run-Command -command " nssm $cmd "
$command = Argv-ToString -arguments ( @ ( $executable ) + $arguments )
$result = Run-Command -command $command
$result . arguments = $command
return $nssm_result
return $ result
}
}
Function Service-Exists
function Get-NssmServiceStatus {
{
[ CmdletBinding ( ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ string ] $ nam e
[ string ] $ servic e
)
)
return [ bool ] ( Get-Service " $name " -ErrorAction SilentlyContinu e)
return Invoke-NssmCommand -arguments @ ( " status " , $servic e)
}
}
Function Nssm-Remove
function Get-NssmServiceParameter {
{
[ CmdletBinding ( ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
[ string ] $service ,
[ Parameter ( Mandatory = $true ) ]
[ Alias ( " param " ) ]
[ string ] $parameter ,
[ Parameter ( Mandatory = $false ) ]
[ string ] $subparameter
)
)
if ( Service-Exists -name $name )
$arguments = @ ( " get " , $service , $parameter )
{
if ( $subparameter -ne " " ) {
if ( ( Get-Service -Name $name ) . Status -ne " Stopped " ) {
$arguments + = $subparameter
$cmd = " stop "" $name "" "
$nssm_result = Nssm-Invoke $cmd
}
$cmd = " remove "" $name "" confirm "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error removing service "" $name "" "
}
$result . changed_by = " remove_service "
$result . changed = $true
}
}
return Invoke-NssmCommand -arguments $arguments
}
}
Function Nssm-Install
function Set-NssmServiceParameter {
{
[ CmdletBinding ( ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ string ] $ nam e,
[ string ] $service ,
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ AllowEmptyString ( ) ]
[ string ] $parameter ,
[ string ] $application
[ Parameter ( Mandatory = $true , ValueFromRemainingArguments = $true ) ]
[ Alias ( " value " ) ]
[ string[] ] $arguments
)
)
if ( ! $application )
return Invoke-NssmCommand -arguments ( @ ( " set " , $service , $parameter ) + $arguments )
{
Throw " Error installing service "" $name "" . No application was supplied. "
}
If ( -Not ( Test-Path -Path $application -PathType Leaf ) ) {
Throw " $application does not exist on the host "
}
}
if ( ! ( Service-Exists -name $name ) )
function Reset-NssmServiceParameter {
{
[ CmdletBinding ( ) ]
$nssm_result = Nssm-Invoke " install "" $name "" "" $application "" "
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $service ,
[ Parameter ( Mandatory = $true ) ]
[ Alias ( " param " ) ]
[ string ] $parameter
)
if ( $nssm_result . rc -ne 0 )
return Invoke-NssmCommand -arguments @ ( " reset " , $service , $parameter )
{
}
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
function Update-NssmServiceParameter {
Throw " Error installing service "" $name "" "
<#
}
. SYNOPSIS
A generic cmdlet to idempotently set a nssm service parameter .
. PARAMETER service
[ String ] The service name
. PARAMETER parameter
[ String ] The name of the nssm parameter to set .
. PARAMETER arguments
[ String[] ] Target value ( or list of value ) or array of arguments to pass to the 'nssm set' command .
. PARAMETER compare
[ scriptblock ] An optionnal idempotency check scriptblock that must return true when
the current value is equal to the desired value . Usefull when 'nssm get' doesn ' t return
the same value as 'nssm set' takes in argument , like for the ObjectName parameter .
#>
[ CmdletBinding ( SupportsShouldProcess = $true ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $service ,
$result . changed_by = " install_service "
[ Parameter ( Mandatory = $true ) ]
$result . changed = $true
[ string ] $parameter ,
} else {
[ Parameter ( Mandatory = $true , ValueFromRemainingArguments = $true ) ]
$nssm_result = Nssm-Invoke " get "" $name "" Application "
[ AllowEmptyString ( ) ]
[ AllowNull ( ) ]
[ Alias ( " value " ) ]
[ string[] ] $arguments ,
if ( $nssm_result . rc -ne 0 )
[ Parameter ( ) ]
{
[ scriptblock ] $compare = { param ( $actual , $expected ) @ ( Compare-Object -ReferenceObject $actual -DifferenceObject $expected ) . Length -eq 0 }
$result . nssm_error_cmd = $cmd
)
$result . nssm_error_log = $nssm_result . stderr
Throw " Error installing service "" $name "" "
}
if ( $nssm_result . stdout . split ( " `n `r " ) [ 0 ] -ne $application )
if ( $null -eq $arguments ) { return }
{
$arguments = @ ( $arguments | Where-Object { $_ -ne '' } )
$cmd = " set "" $name "" Application "" $application "" "
$nssm_result = Nssm-Invoke $cmd
$nssm_result = Get-NssmServiceParameter -service $service -parameter $parameter
if ( $nssm_result . rc -ne 0 )
if ( $nssm_result . rc -ne 0 ) {
{
$result . nssm_error_cmd = $nssm_result . arguments
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
$result . nssm_error_log = $nssm_result . stderr
Throw " Error installing service "" $nam e"" "
Fail-Json -obj $result -message " Error retrieving $parameter for service "" $servic e"" "
}
}
$result . application = " $application "
$result . changed_by = " reinstall_service "
$current_values = @ ( $nssm_result . stdout . split ( " `n `r " ) | Where-Object { $_ -ne '' } )
$result . changed = $true
if ( -not $compare . Invoke ( $current_values , $arguments ) ) {
if ( $PSCmdlet . ShouldProcess ( $service , " Update ' $parameter ' parameter " ) ) {
if ( $arguments . Count -gt 0 ) {
$nssm_result = Set-NssmServiceParameter -service $service -parameter $parameter -arguments $arguments
}
}
else {
$nssm_result = Reset-NssmServiceParameter -service $service -parameter $parameter
}
}
if ( $result . changed )
if ( $nssm_result . rc -ne 0 ) {
{
$result . nssm_error_cmd = $nssm_result . arguments
$applicationPath = ( Get-Item $application ) . DirectoryName
$cmd = " set "" $name "" AppDirectory "" $applicationPath "" "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
$result . nssm_error_log = $nssm_result . stderr
Throw " Error installing service "" $name "" "
Fail-Json -obj $result -message " Error setting $parameter for service "" $service "" "
}
}
}
$script:diff_text + = " - $parameter = $( $current_values -join ', ' ) `n + $parameter = $( $arguments -join ', ' ) `n "
$result . changed_by = $parameter
$result . changed = $true
}
}
}
}
Function ParseAppParameters ( )
function Test-NssmServiceExists {
{
[ CmdletBinding ( ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ AllowEmptyString ( ) ]
[ string ] $service
[ string ] $appParameters
)
)
$escapedAppParameters = $appParameters . TrimStart ( " @ " ) . TrimStart ( " { " ) . TrimEnd ( " } " ) . Replace ( " ; " , " `n " ) . Replace ( " \ " , " \\ " )
return [ bool ] ( Get-Service -Name $service -ErrorAction SilentlyContinue )
return ConvertFrom-StringData -StringData $escapedAppParameters
}
}
Function Nssm-Update-AppParameters
function Invoke-NssmStart {
{
[ CmdletBinding ( ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ string ] $name ,
[ string ] $service
$appParameters ,
[ string ] $appParametersFree
)
)
$cmd = " get "" $name "" AppParameters "
$nssm_result = Invoke-NssmCommand -arguments @ ( " start " , $service )
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
if ( $nssm_result . rc -ne 0 ) {
{
$result . nssm_error_cmd = $nssm_result . arguments
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
$result . nssm_error_log = $nssm_result . stderr
Throw " Error updating AppParameters for service "" $nam e"" "
Fail-Json -obj $result -message " Error starting service "" $servic e"" "
}
}
$appParamKeys = @ ( )
$appParamVals = @ ( )
$singleLineParams = " "
if ( $null -ne $appParameters )
{
$appParametersHash = ParseAppParameters -appParameters $appParameters
$appParamsArray = @ ( )
$appParametersHash . GetEnumerator ( ) | foreach {
$key = $ ( $_ . Name )
$val = $ ( $_ . Value )
$appParamKeys + = $key
$appParamVals + = $val
if ( $key -ne " _ " ) {
$appParamsArray + = $key
}
}
$appParamsArray + = $val
function Invoke-NssmStop {
}
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $service
)
$result . nssm_app_parameters_keys = $appParamKeys
$nssm_result = Invoke-NssmCommand -arguments @ ( " stop " , $service )
$result . nssm_app_parameters_vals = $appParamVals
$singleLineParams = Argv-ToString -arguments $appParamsArray
if ( $nssm_result . rc -ne 0 ) {
$result . nssm_error_cmd = $nssm_result . arguments
$result . nssm_error_log = $nssm_result . stderr
Fail-Json -obj $result -message " Error stopping service "" $service "" "
}
}
elseif ( $null -ne $appParametersFree ) {
$result . nssm_app_parameters_free_form = $appParametersFree
$singleLineParams = $appParametersFree
}
}
$result . nssm_app_parameters = $appParameters
function Start-NssmService {
$result . nssm_single_line_app_parameters = $singleLineParams
[ CmdletBinding ( SupportsShouldProcess = $true ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $service
)
$currentStatus = Get-NssmServiceStatus -service $service
if ( $nssm_result . stdout . split ( " `n `r " ) [ 0 ] -ne $singleLineParams )
if ( $ currentStatus. rc -ne 0 ) {
{
$result . nssm_error_cmd = $currentStatus . arguments
# Escape argument line to preserve possible quotes and spaces
$result . nssm_error_log = $currentStatus . stderr
$singleLineParams = Escape-Argument -argument $singleLineParams
Fail-Json -obj $result -message " Error starting service "" $service "" "
$cmd = " set "" $name "" AppParameters $singleLineParams "
}
$nssm_result = Nssm-Invoke $cmd
if ( $currentStatus . stdout -notlike " *SERVICE_RUNNING* " ) {
if ( $PSCmdlet . ShouldProcess ( $service , " Start service " ) ) {
switch -wildcard ( $currentStatus . stdout ) {
" *SERVICE_STOPPED* " { Invoke-NssmStart -service $service }
if ( $nssm_result . rc -ne 0 )
" *SERVICE_CONTINUE_PENDING* " { Invoke-NssmStop -service $service ; Invoke-NssmStart -service $service }
{
" *SERVICE_PAUSE_PENDING* " { Invoke-NssmStop -service $service ; Invoke-NssmStart -service $service }
$result . nssm_error_cmd = $cmd
" *SERVICE_PAUSED* " { Invoke-NssmStop -service $service ; Invoke-NssmStart -service $service }
$result . nssm_error_log = $nssm_result . stderr
" *SERVICE_START_PENDING* " { Invoke-NssmStop -service $service ; Invoke-NssmStart -service $service }
Throw " Error updating AppParameters for service "" $name "" "
" *SERVICE_STOP_PENDING* " { Invoke-NssmStop -service $service ; Invoke-NssmStart -service $service }
}
}
}
$result . changed_by = " update_app_parameters "
$result . changed_by = " start_service "
$result . changed = $true
$result . changed = $true
}
}
}
}
Function Nssm-Set-Output-Files
function Stop-NssmService {
{
[ CmdletBinding ( SupportsShouldProcess = $true ) ]
[ CmdletBinding ( ) ]
param (
param (
[ Parameter ( Mandatory = $true ) ]
[ Parameter ( Mandatory = $true ) ]
[ string ] $name ,
[ string ] $service
[ string ] $stdout ,
[ string ] $stderr
)
)
$cmd = " get "" $name "" AppStdout "
$currentStatus = Get-NssmServiceStatus -service $service
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error retrieving existing stdout file for service "" $name "" "
}
if ( $nssm_result . stdout . split ( " `n `r " ) [ 0 ] -ne $stdout )
if ( $currentStatus . rc -ne 0 ) {
{
$result . nssm_error_cmd = $currentStatus . arguments
if ( ! $stdout )
$result . nssm_error_log = $currentStatus . stderr
{
Fail-Json -obj $result -message " Error stopping service "" $service "" "
$cmd = " reset "" $name "" AppStdout "
} else {
$cmd = " set "" $name "" AppStdout $stdout "
}
}
$nssm_result = Nssm-Invoke $cmd
if ( $currentStatus . stdout -notlike " *SERVICE_STOPPED* " ) {
if ( $PSCmdlet . ShouldProcess ( $service , " Stop service " ) ) {
if ( $nssm_result . rc -ne 0 )
Invoke-NssmStop -service $service
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error setting stdout file for service "" $name "" "
}
}
$result . changed_by = " s et_stdout "
$result . changed_by = " stop_service "
$result . changed = $true
$result . changed = $true
}
}
$cmd = " get "" $name "" AppStderr "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error retrieving existing stderr file for service "" $name "" "
}
}
if ( $nssm_result . stdout . split ( " `n `r " ) [ 0 ] -ne $stderr )
if ( ( $null -ne $appParameters ) -and ( $null -ne $appArguments ) ) {
{
Fail-Json $result " 'app_parameters' and 'arguments' are mutually exclusive but have both been set. "
if ( ! $stderr )
{
$cmd = " reset "" $name "" AppStderr "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error clearing stderr file setting for service "" $name "" "
}
}
} else {
$cmd = " set "" $name "" AppStderr $stderr "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
# Backward compatibility for old parameters style. Remove the block bellow in 2.12
{
if ( $null -ne $appParameters ) {
$result . nssm_error_cmd = $cmd
Add-DeprecationWarning -obj $result -message " The parameter 'app_parameters' will be removed soon, use 'arguments' instead " -version 2.12
$result . nssm_error_log = $nssm_result . stderr
Throw " Error setting stderr file for service "" $name "" "
}
}
$result . changed_by = " set_stderr "
if ( $appParameters -isnot [ string ] ) {
$result . changed = $true
Fail-Json -obj $result -message " The app_parameters parameter must be a string representing a dictionary. "
}
}
###
# Convert dict-as-string form to list
# Setup file rotation so we don't accidentally consume too much disk
$escapedAppParameters = $appParameters . TrimStart ( " @ " ) . TrimStart ( " { " ) . TrimEnd ( " } " ) . Replace ( " ; " , " `n " ) . Replace ( " \ " , " \\ " )
###
$appParametersHash = ConvertFrom-StringData -StringData $escapedAppParameters
#set files to overwrite
$cmd = " set "" $name "" AppStdoutCreationDisposition 2 "
$nssm_result = Nssm-Invoke $cmd
$cmd = " set "" $name "" AppStderrCreationDisposition 2 "
$nssm_result = Nssm-Invoke $cmd
#enable file rotation
$cmd = " set "" $name "" AppRotateFiles 1 "
$nssm_result = Nssm-Invoke $cmd
#don't rotate until the service restarts
$cmd = " set "" $name "" AppRotateOnline 0 "
$nssm_result = Nssm-Invoke $cmd
#both of the below conditions must be met before rotation will happen
#minimum age before rotating
$cmd = " set "" $name "" AppRotateSeconds 86400 "
$nssm_result = Nssm-Invoke $cmd
#minimum size before rotating
$appParamsArray = @ ( )
$cmd = " set "" $name "" AppRotateBytes 104858 "
$appParametersHash . GetEnumerator ( ) | Foreach-Object {
$nssm_result = Nssm-Invoke $cmd
if ( $_ . Name -ne " _ " ) {
$appParamsArray + = $_ . Name
}
}
$appParamsArray + = $_ . Value
Function Nssm-Update-Credentials
{
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name ,
[ Parameter ( Mandatory = $false ) ]
[ string ] $user ,
[ Parameter ( Mandatory = $false ) ]
[ string ] $password
)
$cmd = " get "" $name "" ObjectName "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error updating credentials for service "" $name "" "
}
}
$appArguments = @ ( $appParamsArray )
if ( $user ) {
# The rest of the code should use only the new $appArguments variable
if ( ! $password ) {
Throw " User without password is informed for service "" $name "" "
}
else {
$fullUser = $user
If ( -Not ( $user . contains ( " @ " ) ) -And ( $user . Split ( " \ " ) . count -eq 1 ) ) {
$fullUser = " .\ " + $user
}
}
If ( $nssm_result . stdout . split ( " `n `r " ) [ 0 ] -ne $fullUser ) {
if ( $state -in @ ( " started " , " stopped " , " restarted " ) ) {
$cmd = Argv-ToString @ ( " set " , $name , " ObjectName " , $fullUser , $password )
Add-DeprecationWarning -obj $result -message " The values 'started', 'stopped', and 'restarted' for 'state' will be removed soon, use the win_service module to start or stop the service instead " -version 2.12
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error updating credentials for service "" $name "" "
}
}
if ( $params . ContainsKey ( 'start_mode' ) ) {
$result . changed_by = " update_credentials "
Add-DeprecationWarning -obj $result -message " The parameter 'start_mode' will be removed soon, use the win_service module instead " -version 2.12
$result . changed = $true
}
}
if ( $null -ne $dependencies ) {
Add-DeprecationWarning -obj $result -message " The parameter 'dependencies' will be removed soon, use the win_service module instead " -version 2.12
}
}
if ( $null -ne $user ) {
Add-DeprecationWarning -obj $result -message " The parameter 'user' will be removed soon, use the win_service module instead " -version 2.12
}
}
if ( $null -ne $password ) {
Add-DeprecationWarning -obj $result -message " The parameter 'password' will be removed soon, use the win_service module instead " -version 2.12
}
}
Function Nssm-Update-Dependencies
if ( $state -ne 'absent' ) {
{
if ( $null -eq $application ) {
[ CmdletBinding ( ) ]
Fail-Json -obj $result -message " The application parameter must be defined when the state is not absent. "
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name ,
[ Parameter ( Mandatory = $false ) ]
$dependencies
)
if ( $null -eq $dependencies ) {
# Don't make any change to dependencies if the parameter is omitted
return
}
}
$cmd = " get "" $name "" DependOnService "
if ( -not ( Test-Path -LiteralPath $application -PathType Leaf ) ) {
$nssm_result = Nssm-Invoke $cmd
Fail-Json -obj $result -message " The application specified "" $application "" does not exist on the host. "
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error updating dependencies for service "" $name "" "
}
}
$current_dependencies = @ ( $nssm_result . stdout . split ( " `n `r " ) | where { $_ -ne '' } )
if ( $null -eq $appDirectory ) {
$appDirectory = ( Get-Item -LiteralPath $application ) . DirectoryName
If ( @ ( Compare-Object -ReferenceObject $current_dependencies -DifferenceObject $dependencies ) . Length -ne 0 ) {
$dependencies_str = Argv-ToString -arguments $dependencies
$cmd = " set "" $name "" DependOnService $dependencies_str "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
Throw " Error updating dependencies for service "" $name "" "
}
}
$result . changed_by = " update-dependencies "
if ( $user -and -not $password ) {
$result . changed = $true
Fail-Json -obj $result -message " User without password is informed for service "" $name "" "
}
}
}
}
Function Nssm-Update-StartMode
{
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name ,
[ Parameter ( Mandatory = $true ) ]
[ string ] $mode
)
$cmd = " get "" $name "" Start "
$service_exists = Test-NssmServiceExists -service $name
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
if ( $state -eq 'absent' ) {
{
if ( $service_exists ) {
$result . nssm_error_cmd = $cmd
if ( -not $check_mode ) {
$result . nssm_error_log = $nssm_result . stderr
if ( ( Get-Service -Name $name ) . Status -ne " Stopped " ) {
Throw " Error updating start mode for service "" $name "" "
$nssm_result = Invoke-NssmStop -service $name
}
}
$modes = @ { " auto " = " SERVICE_AUTO_START " ; " delayed " = " SERVICE_DELAYED_AUTO_START " ; " manual " = " SERVICE_DEMAND_START " ; " disabled " = " SERVICE_DISABLED " }
$nssm_result = Invoke-NssmCommand -arguments @ ( " remove " , $name , " confirm " )
$mappedMode = $modes . $mode
if ( $nssm_result . stdout -notlike " * $mappedMode * " ) {
$cmd = " set "" $name "" Start $mappedMode "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
if ( $nssm_result . rc -ne 0 ) {
{
$result . nssm_error_cmd = $nssm_result . arguments
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $nssm_result . stderr
$result . nssm_error_log = $nssm_result . stderr
Throw " Error updating start mode for service "" $name "" "
Fail-Json -obj $result -message " Error removing service "" $name "" "
}
}
}
$result . changed_by = " start_mode "
$diff_text + = " -[ $name ] "
$result . changed_by = " remove_service "
$result . changed = $true
$result . changed = $true
}
}
}
} else {
$diff_text_added_prefix = ''
Function Nssm-Get-Status
if ( -not $service_exists ) {
{
if ( -not $check_mode ) {
[ CmdletBinding ( ) ]
$nssm_result = Invoke-NssmCommand -arguments @ ( " install " , $name , $application )
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
)
$cmd = " status "" $name "" "
$nssm_result = Nssm-Invoke $cmd
return $nssm_result
if ( $nssm_result . rc -ne 0 ) {
$result . nssm_error_cmd = $nssm_result . arguments
$result . nssm_error_log = $nssm_result . stderr
Fail-Json -obj $result -message " Error installing service "" $name "" "
}
$service_exists = $true
}
}
Function Nssm-Start
$diff_text_added_prefix = '+'
{
$result . changed_by = " install_service "
[ CmdletBinding ( ) ]
$result . changed = $true
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
)
$currentStatus = Nssm-Get -Status -name $name
if ( $currentStatus . rc -ne 0 )
{
$result . nssm_error_cmd = $cmd
$result . nssm_error_log = $currentStatus . stderr
Throw " Error starting service "" $name "" "
}
}
switch -wildcard ( $currentStatus . stdout )
$diff_text + = " $diff_text_added_prefix [ $name ] `n "
{
" *SERVICE_RUNNING* " { <# Nothing to do #> }
" *SERVICE_STOPPED* " { Nssm-Start -Service -Command -name $name }
" *SERVICE_CONTINUE_PENDING* " { Nssm-Stop -Service -Command -name $name ; Nssm-Start -Service -Command -name $name }
# We cannot configure a service that was created above in check mode as it won't actually exist
" *SERVICE_PAUSE_PENDING* " { Nssm-Stop -Service -Command -name $name ; Nssm-Start -Service -Command -name $name }
if ( $service_exists ) {
" *SERVICE_PAUSED* " { Nssm-Stop -Service -Command -name $name ; Nssm-Start -Service -Command -name $name }
$common_params = @ {
" *SERVICE_START_PENDING* " { Nssm-Stop -Service -Command -name $name ; Nssm-Start -Service -Command -name $name }
service = $name
" *SERVICE_STOP_PENDING* " { Nssm-Stop -Service -Command -name $name ; Nssm-Start -Service -Command -name $name }
WhatIf = $check_mode
}
}
}
Function Nssm-Start-Service-Command
Update-NssmServiceParameter -parameter " Application " -value $application @common_params
{
Update-NssmServiceParameter -parameter " DisplayName " -value $display_name @common_params
[ CmdletBinding ( ) ]
Update-NssmServiceParameter -parameter " Description " -value $description @common_params
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
)
$cmd = " start "" $name "" "
Update-NssmServiceParameter -parameter " AppDirectory " -value $appDirectory @common_params
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
if ( $null -ne $appArguments ) {
{
$singleLineParams = " "
$result . nssm_error_cmd = $cmd
if ( $appArguments -is [ array ] ) {
$result . nssm_error_log = $nssm_result . stderr
$singleLineParams = Argv-ToString -arguments $appArguments
Throw " Error starting service "" $name "" "
} else {
$singleLineParams = $appArguments . ToString ( )
}
}
$result . changed_by = " start_service "
$result . nssm_app_parameters = $appArguments
$result . changed = $true
$result . nssm_single_line_app_parameters = $singleLineParams
}
Function Nssm-Stop-Service-Command
Update-NssmServiceParameter -parameter " AppParameters " -value $singleLineParams @common_params
{
}
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
)
$cmd = " stop "" $name "" "
$nssm_result = Nssm-Invoke $cmd
Update-NssmServiceParameter -parameter " AppStdout " -value $stdoutFile @common_params
Update-NssmServiceParameter -parameter " AppStderr " -value $stderrFile @common_params
if ( $nssm_result . rc -ne 0 )
###
{
# Setup file rotation so we don't accidentally consume too much disk
$result . nssm_error_cmd = $cmd
###
$result . nssm_error_log = $nssm_result . stderr
Throw " Error stopping service "" $name "" "
}
$result . changed_by = " stop_service_command "
#set files to overwrite
$result . changed = $true
Update-NssmServiceParameter -parameter " AppStdoutCreationDisposition " -value 2 @common_params
}
Update-NssmServiceParameter -parameter " AppStderrCreationDisposition " -value 2 @common_params
Function Nssm-Stop
#enable file rotation
{
Update-NssmServiceParameter -parameter " AppRotateFiles " -value 1 @common_params
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
)
$currentStatus = Nssm-Get -Status -name $name
#don't rotate until the service restarts
Update-NssmServiceParameter -parameter " AppRotateOnline " -value 0 @common_params
if ( $currentStatus . rc -ne 0 )
#both of the below conditions must be met before rotation will happen
{
#minimum age before rotating
$result . nssm_error_cmd = $cmd
Update-NssmServiceParameter -parameter " AppRotateSeconds " -value 86400 @common_params
$result . nssm_error_log = $currentStatus . stderr
Throw " Error stopping service "" $name "" "
}
if ( $currentStatus . stdout -notlike " *SERVICE_STOPPED* " )
#minimum size before rotating
{
Update-NssmServiceParameter -parameter " AppRotateBytes " -value 104858 @common_params
$cmd = " stop "" $name "" "
$nssm_result = Nssm-Invoke $cmd
if ( $nssm_result . rc -ne 0 )
############## DEPRECATED block since 2.8. Remove in 2.12 ##############
{
Update-NssmServiceParameter -parameter " DependOnService " -arguments $dependencies @common_params
$result . nssm_error_cmd = $cmd
if ( $user ) {
$result . nssm_error_log = $nssm_result . stderr
$fullUser = $user
Throw " Error stopping service "" $name "" "
if ( -Not ( $user . contains ( " @ " ) ) -And ( $user . Split ( " \ " ) . count -eq 1 ) ) {
$fullUser = " .\ " + $user
}
}
$result . changed_by = " stop_service "
# Use custom compare callback to test only the username (and not the password)
$result . changed = $true
Update-NssmServiceParameter -parameter " ObjectName " -arguments @ ( $fullUser , $password ) -compare { param ( $actual , $expected ) $actual [ 0 ] -eq $expected [ 0 ] } @common_params
}
}
$mappedMode = $start_modes_map . $startMode
Update-NssmServiceParameter -parameter " Start " -value $mappedMode @common_params
if ( $state -in " stopped " , " restarted " ) {
Stop-NssmService @common_params
}
}
Function Nssm-Restart
if ( $state -in " started " , " restarted " ) {
{
Start-NssmService @common_params
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ string ] $name
)
Nssm-Stop -Service -Command -name $name
Nssm-Start -Service -Command -name $name
}
Function NssmProcedure
{
Nssm-Install -name $name -application $application
Nssm-Update -AppParameters -name $name -appParameters $appParameters -appParametersFree $appParametersFree
Nssm-Set -Output -Files -name $name -stdout $stdoutFile -stderr $stderrFile
Nssm-Update -Dependencies -name $name -dependencies $dependencies
Nssm-Update -Credentials -name $name -user $user -password $password
Nssm-Update -StartMode -name $name -mode $startMode
}
}
########################################################################
Try
{
switch ( $state )
{
" absent " {
Nssm-Remove -name $name
}
" present " {
NssmProcedure
}
" started " {
NssmProcedure
Nssm-Start -name $name
}
}
" stopped " {
NssmProcedure
Nssm-Stop -name $name
}
}
" restarted " {
NssmProcedure
if ( $diff_mode -and $result . changed -eq $true ) {
Nssm-Restart -name $name
$result . diff = @ {
prepared = $diff_text
}
}
}
}
Exit-Json $result
Exit-Json $result
}
Catch
{
Fail-Json $result $_ . Exception . Message
}