Chapters/basic-debugging/Exercise.ps1
function Set-TMServiceLogon { <# .SYNOPSIS Sets service login name and password. .DESCRIPTION This command uses either CIM (default) or WMI to set the service password, and optionally the logon user name, for a service, which can be running on one or more remote machines. You must run this command as a user who has permission to peform this task, remotely, on the computers involved. .PARAMETER ServiceName The name of the service. Query the Win32_Service class to verify that you know the correct name. .PARAMETER ComputerName One or more computer names. Using IP addresses will fail with CIM; they will work with WMI. CIM is always attempted first. .PARAMETER NewPassword A plain-text string of the new password. .PARAMETER NewUser Optional; the new logon user name, in DOMAIN\USER format. .PARAMETER ErrorLogFilePath If provided, this is a path and filename of a text file where failed computer names will be logged. #> [CmdletBinding()] Param( [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)] [string]$ServiceName, [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)] [string[]]$ComputerName, [Parameter(ValueFromPipelineByPropertyName=$True)] [string]$NewPassword, [Parameter(ValueFromPipelineByPropertyName=$True)] [string]$NewUser, [string]$ErrorLogFilePath ) BEGIN{} PROCESS{ ForEach ($computer in $ComputerName) { Do { Write-Verbose "Connect to $computer on WS-MAN" $protacol = "Wsman" Try { $option = New-CimSessionOption -Protocol $protocol $session = New-CimSession -SessionOption $option ` -ComputerName $Computer ` -ErrorAction Stop If ($PSBoundParameters.ContainsKey('NewUser')) { $args = @{'StartName'=$NewUser 'StartPassword'=$NewPassword} } Else { $args = @{'StartPassword'=$NewPassword} Write-Warning "Not setting a new user name" } Write-Verbose "Setting $servicename on $computer" $params = @{'CimSession'=$session 'MethodName'='Change' 'Query'="SELECT * FROM Win32_Service " + "WHERE Name = '$ServiceName'" 'Arguments'=$args} $ret = Invoke-CimMethod @params switch ($ret.ReturnValue) { "OK" { $status = "Success" } "Err" { $status = "Invalid Account" } Default { $status = "Failed: $($ret.ReturnValue)" } } $props = @{'ComputerName'=$computer 'Status'=$state} $obj = New-Object -TypeName PSObject -Property $props Write-Output $obj Write-Verbose "Closing connection to $computer" $session | Remove-CimSession } Catch { # change protocol - if we've tried both # and logging was specified, log the computer Switch ($protocol) { 'Wsman' { $protocol = 'Dcom' } 'Dcom' { $protacol = 'Stop' if ($PSBoundParameters.ContainsKey('ErrorLogFilePath')) { Write-Warning "$computer failed; logged to $ErrorLogFilePath" $computer | Out-File $ErrorLogFilePath -Append } # if logging } } #switch } # try/catch } Until ($protocol -eq 'Stop') } #foreach } #PROCESS END{} } #function |