Problem:
When I run the following cmdlet, where ck-acer is a remote computer in a homegroup; it works fine.
$os=Get-WmiObject -Class Win32_OperatingSystem -ComputerName ck-acer
$os.Win32Shutdown(0) # 0=Logoff, 1=ShutDown, 2= Restart, 8=PowerOff
But when I log on again and change the parameter value to 1, the cmdlet does not shutdown the remote PC as expected. It returns a value of 1191. The same thing for the value 2 or 8.
Reason:
1191 indicates the system shutdown cannot be initiated because there are other users logged on to the computer.
See http://www.mathemainzel.info/files/w32errcodes.html for more return values
Solution 1:
Run logoff first, then other action (do not logon again!). For example, the cmdlets below will shutdown the remote machine ck-acer
$os=Get-WmiObject -Class Win32_OperatingSystem -ComputerName ck-acer
$os.Win32Shutdown(0)
$os.Win32Shutdown(1)
Solution 2 - Implementing the -force parameter:
Function Set-ComputerState
{
[CmdletBinding(SupportsShouldProcess = $True,
ConfirmImpact = 'High')]
param (
[Parameter(Mandatory = $True,
ValueFromPipeline = $True)]
[string[]]$ComputerName,
[Parameter(Mandatory = $True)]
[ValidateSet("LogOff","Shutdown","Restart","PowerOff")]
[string]$Action,
[switch]$Force
)
Begin {
Write-Verbose "Starting Set-Computerstate"
#set the state value
Switch ($Action) {
"LogOff" { $Flag=0}
"ShutDown" { $Flag=1}
"Restart" { $Flag=2}
"PowerOff" { $Flag=8}
}
if ($Force) {
Write-Verbose "Force enabled"
$Flag+=4
}
} #Begin
Process {
Foreach ($computer in $Computername) {
Write-Verbose "Processing $computer"
$os=Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computer
if ($PSCmdlet.ShouldProcess($computer)) {
Write-Verbose "Passing flag $flag"
$os.Win32Shutdown($flag)
}
} #foreach
} #Process
End {
Write-Verbose "Ending Set-Computerstate"
} #end
}
## Test it
Set-ComputerState –computername ck-acer –Action shutdown –Force -verbose