Public/Set-PowercfgScheme.ps1
<#
.Synopsis Modifies, duplicates, deletes, or changes the power plan. .DESCRIPTION Parameter sets offer renaming a power plan, duplicating it (duplicates are appended with "-Copy"), deleting a power plan, or setting the active power plan. Can pipe Get-PowercfgSettings with -ComputerName to set on remote computer, or specify -ComputerName inside function. .EXAMPLE Set-PowercfgScheme -PowerScheme Balanced -Active Sets current power plan to "Balanced", if present. .EXAMPLE Get-PowercfgSettings -ComputerName $ComputerName -List | Set-PowercfgScheme "High Performance" -Active Sets a targeted computer (requires -List switch) from pipeline to set the active scheme to "High Performance". .EXAMPLE Get-PowercfgSettings -ComputerName $ComputerName -List -Name "High Performance" | Set-PowercfgScheme -Active Similar to the previous example, but the power scheme is specified to the left of the pipe. This allows Get-PowercfgSettings to select a single power plan and pipe one object to Set-PowercfgScheme to set as the active plan. .EXAMPLE Set-PowercfgScheme -ComputerName $ComputerName -PowerScheme Balanced -Duplicate Duplicates the "Balanced" power plan. New name will be called "Balanced-Copy" .EXAMPLE Set-PowercfgScheme -PowerScheme "Power Saving" -Rename "Low Power" Renames "Power Saving" power plan to "Low Power" .PARAMETER ComputerName Target a remote computer. Uses Invoke-Command and relies on WinRM .PARAMETER PowerScheme Name of power plan to target for selected action .PARAMETER Active Set the power plan as the active plan .PARAMETER Delete Deletes the selected power plan .PARAMETER Duplicate Duplicates the selected power plan. Copies will be named similarly, with "-Copy" appended to it. .PARAMETER Rename Renames a selected PowerScheme .PARAMETER Description Optional. Set a description for a PowerScheme when renaming it. .INPUTS ComputerName PowerScheme .OUTPUTS [PowerCfgPlan] .NOTES Relies on WinRM to use Invoke-Command when targeting remote computers. .FUNCTIONALITY Uses powercfg /s #> function Set-PowercfgScheme { [CmdletBinding()] Param ( [Parameter( ValueFromPipelineByPropertyName )] [Alias("CN")] [String] $ComputerName, [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateNotNullOrEmpty()] [PowerCfgPlan] $PowerScheme, [Parameter( ParameterSetName="Active" )] [Switch] $Active, [Parameter( ParameterSetName="Delete" )] [Switch] $Delete, [Parameter( ParameterSetName="Duplicate" )] [Switch] $Duplicate, [Parameter( ParameterSetName="Rename", Mandatory )] [ValidateNotNullOrEmpty()] [String] $Rename, [Parameter( ParameterSetName="Rename", Position=1 )] [String] $Description ) Begin { # Count null powerschemes as each one passes through pipe. If this equals 0 by End{}, than no matching scheme was found. # Only necessary for pipeline compatibility. [int]$tallyScheme=0 } Process { # Computername handler first in Process block for pipeline compatibility if(!$cfg){ if($ComputerName){ Try{ $cfg = Invoke-Command $ComputerName { powercfg /l } -ErrorAction Stop $DescList = Invoke-Command $ComputerName { (gcim Win32_PowerPlan -Namespace root\cimv2\power) } -ErrorAction SilentlyContinue } Catch{ throw } Write-Verbose "Queried scheme list on $ComputerName" } Else{ $cfg = powercfg /l $DescList = (gcim Win32_PowerPlan -Namespace root\cimv2\power) Write-Verbose "Queried scheme list" } } # Parse out the heading $cfg = $cfg[3..(($cfg.count)-1)] # Build out scheme table to translate between names and guids $schemeTable = @() foreach($scheme in $cfg){ $null = $scheme -match "\((.+)\)";$name = $Matches[1] $null = $scheme -match "\s{1}(\S+\d+\S+)\s{1}";$guid = $Matches[1] $Desc = $DescList.where({$_.ElementName -eq $name}).Description if($scheme -match "\*$"){$active = $true} elseif($scheme -notmatch "\*$"){$active = $false} $temp = [PSCustomObject]@{ Name=$name Description=$Desc Guid=[Guid]$guid Active=[bool]$active } [PowerCfgPlan]$temp = $temp $schemeTable += $temp $null = Remove-Variable temp -Force } <#$Current = $schemeTable.Where({$_.Active}).Name if($null -ne $Current -and $PowerScheme -match $Current){ Write-Warning "Chosen PowerScheme, $Current, is already active." }#> ### NOT PIPELINE COMPATIBLE ### if($schemeTable.Guid.Guid -contains $PowerScheme.Guid.Guid){ $selPowerScheme = $PowerScheme.Guid.Guid Write-Verbose "Acquired guid from pipeline" } else{ $selPowerScheme = ($schemeTable.Where({$_.Name -like "*$($PowerScheme.Name)*"}).Guid.Guid) } # Should check for an exact match and prioritize over matches, in cases where you want to set "Balanced" to active, but "Balanced-Copy" is an additional match if($selPowerScheme.count -gt 1){ $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( [System.ArgumentOutOfRangeException]::new( "-PowerScheme", "$($PowerScheme.Name) matches multiple values." ), "PowerScheme.>1", [System.Management.Automation.ErrorCategory]::LimitsExceeded, $PowerScheme ) ) } if($null -ne $selPowerScheme){ $null = $tallyScheme++ # Force PowerScheme name to match exactly $PowerSchemeName = $schemeTable.Name | Where-Object {$_ -match $PowerScheme.Name} Write-Verbose "Determined power scheme, $PowerSchemeName, and acquired guid" if($PSCmdlet.ParameterSetName -eq "Active"){ if($ComputerName){ Try{ Invoke-Command $ComputerName { powercfg /s $using:selPowerScheme } Get-PowercfgSettings -ComputerName $ComputerName -List } Catch{ throw } Write-Verbose "Set active scheme on $ComputerName" } Else{ powercfg /s $selPowerScheme Write-Verbose "Set active scheme" Get-PowercfgSettings -List } } if($PSCmdlet.ParameterSetName -eq "Delete"){ if($ComputerName){ Try{ Invoke-Command $ComputerName { powercfg /d $using:selPowerScheme } Get-PowercfgSettings -ComputerName $ComputerName -List } Catch{ throw } Write-Verbose "Deleted scheme from $ComputerName" } Else{ powercfg /d $selPowerScheme Write-Verbose "Deleted scheme" Get-PowercfgSettings -List } } if($PSCmdlet.ParameterSetName -eq "Duplicate"){ if($ComputerName){ Try{ Invoke-Command $ComputerName { $null = powercfg /duplicatescheme $using:selPowerScheme } $NewList = Get-PowercfgSettings -ComputerName $ComputerName -List Invoke-Command $ComputerName { $null = powercfg /changename (Compare-Object $using:schemeTable.Guid.Guid $using:NewList.Guid.Guid).InputObject ("$($using:PowerSchemeName)-Copy") } Get-PowercfgSettings -ComputerName $ComputerName -List } Catch{ throw } Write-Verbose "Duplicated scheme on $ComputerName" } Else{ $null = powercfg /duplicatescheme $selPowerScheme $NewList = Get-PowercfgSettings -List powercfg /changename (Compare-Object $schemeTable.Guid.Guid $NewList.Guid.Guid).InputObject ("$($PowerSchemeName)-Copy") Write-Verbose "Duplicated scheme" Get-PowercfgSettings -List } } if($PSCmdlet.ParameterSetName -eq "Rename"){ # Look into splatting this, instead if($ComputerName){ Try{ if(!($Description)){ Invoke-Command $ComputerName { powercfg /changename $using:selPowerScheme $Rename } } else{ Invoke-Command $ComputerName { powercfg /changename $using:selPowerScheme $Rename $Description } } Get-PowercfgSettings -ComputerName $ComputerName -List } Catch{ throw } Write-Verbose "Renamed scheme on $ComputerName" } Else{ if(!($Description)){ powercfg /changename $selPowerScheme $Rename } else{ powercfg /changename $selPowerScheme $Rename $Description } Write-Verbose "Duplicated scheme" Get-PowercfgSettings -List } } } } End { # The error if a bad PowerScheme name is entered. if($tallyScheme -eq 0){ $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( [System.ArgumentException]::new( "$($PowerScheme.Name) not found", "-PowerScheme" ), "PowerScheme.notfound", [System.Management.Automation.ErrorCategory]::ObjectNotFound, $PowerScheme ) ) } } } |