Public/Suspend-Computer.ps1
|
<#
.SYNOPSIS Puts one or more computers into a low-power state (sleep or hibernate). .DESCRIPTION Suspend-Computer completes the *-Computer power lifecycle family (Stop-Computer, Restart-Computer) with the missing suspend state. On Windows the cmdlet calls the documented SetSuspendState API from powrprof.dll via P/Invoke. On Linux it invokes systemctl (or loginctl) with the suspend or hibernate action. On macOS it invokes pmset sleepnow. Non-systemd Linux systems are not supported yet. Without parameters, the cmdlet suspends the local computer to sleep. Use -Hibernate to hibernate instead (Windows and Linux only). Use -ComputerName to suspend remote computers over PowerShell remoting (WinRM or SSH); the module does not need to be installed on the remote computer. .PARAMETER ComputerName Specifies the target computers. The default is the local computer. Accepts pipeline input. Remote computers require PowerShell remoting (WinRM or SSH) to be enabled. .PARAMETER Hibernate Hibernates the target (S4) instead of entering sleep (S3 / Modern Standby). Not supported on macOS. On Linux, hibernation must be available (the 'disk' power state in /sys/power/state). .PARAMETER Force Suspends without prompting for confirmation and requests a forced (critical) suspend so the system does not wait for applications. .INPUTS System.String Computer names from the pipeline. .OUTPUTS None .EXAMPLE Suspend-Computer -WhatIf Shows what would happen without suspending anything. .EXAMPLE Suspend-Computer Prompts for confirmation, then puts the local computer to sleep. .EXAMPLE Suspend-Computer -Hibernate -Force Hibernates the local computer immediately, without a confirmation prompt. .EXAMPLE Suspend-Computer -ComputerName WORKSTATION-07, WORKSTATION-12 -Confirm:$false Suspends two remote computers over PowerShell remoting without a prompt. .NOTES Implements the community request tracked in https://github.com/PowerShell/PowerShell/issues/28164. The PowerShell Cmdlets Working Group recommended this functionality be delivered as a community module on the PowerShell Gallery. #> function Suspend-Computer { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param( [Parameter(Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string[]]$ComputerName, [switch]$Hibernate, [switch]$Force ) begin { $targetComputers = [System.Collections.Generic.List[string]]::new() } process { foreach ($computerName in $ComputerName) { $targetComputers.Add($computerName) } } end { if ($targetComputers.Count -eq 0) { $targetComputers.Add('localhost') } foreach ($computer in $targetComputers) { $powerState = if ($Hibernate.IsPresent) { 'hibernate' } else { 'sleep' } if ($Force.IsPresent -or $PSCmdlet.ShouldProcess($computer, ("Enter the '{0}' power state" -f $powerState))) { try { if (Test-BsnLocalComputer -ComputerName $computer) { Invoke-BsnLocalSuspend -Hibernate:$Hibernate.IsPresent -Force:$Force.IsPresent } else { # Ship the self-contained action script to the remote machine; # the module itself does not need to be installed remotely. $null = Invoke-Command -ComputerName $computer -FilePath $script:SuspendActionScriptPath -ArgumentList @([bool]$Hibernate.IsPresent, [bool]$Force.IsPresent) -ErrorAction 'Stop' } } catch { Write-Error -Exception $_.Exception -ErrorId 'SuspendComputerFailed' -Category 'OperationStopped' -TargetObject $computer } } } } } |