PSPowercfg.psm1
<# .SYNOPSIS PowerShell Module to interact with Powercfg .DESCRIPTION PowerShell Module to interact with Powercfg .NOTES Author : Simon Godefroy - Simon.Godefroy@FocusedIT.co.uk Version : 1.0.1 Date : 2022.04.18 Update : 1.0.1 SG - 2022.04.18 Minor update Update : 1.0.0 SG - 2022.04.18 Initial Script .LINK http://www.FocusedIT.co.uk #> function Test-Administrator { $user = [Security.Principal.WindowsIdentity]::GetCurrent(); (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } function Invoke-MultiChoice { <# .SYNOPSIS Generate a Multichoice from multi-valued object and return the selected object .DESCRIPTION Generate a Multichoice from multi-valued object and return the selected object (can accept pipeline input) .EXAMPLE Invoke-MultiChoice -Input $ListOfNames .EXAMPLE $ListOfComputers | Invoke-MultiChoice -Property ComputerName .NOTES Author : Simon Godefroy - Simon.Godefroy@FocusedIT.co.uk Version : 1.0.0 Date : 2022.04.18 Update : 1.0.0 SG - 2022.04.18 Initial Script .LINK http://www.FocusedIT.co.uk #> [CmdletBinding()] param( [Parameter(ValueFromPipeline=$True)] $Input, [Parameter(ValueFromPipeline=$False)] $Property ) begin{ $Items = @() } process{ $Items += $Input } end{ $InputCount = $Items.count $Max = $InputCount -1 $i = 0 while($i -le $Max){ if($Property){ $Current = ($Items[$i]).$Property }else{ $Current = $Items[$i] } Write-Host "$i $Current " $i ++ } $Choice = Read-Host "Enter Selection Number" if($Choice -match "\d{1}"){ $Result = $Items[$Choice] }else{ $Search = $Items | ?{$_ -match $Choice} if($Search.count -eq 1){ $Result = $Search }else{ Write-Warning "Please be more specific.." } } return $Result } } function Get-PowercfgSettings{ $CurrentScheme = Powercfg -getactivescheme $CurrentScheme = $currentScheme.split("()") $CurrentGuid = ($currentScheme[0]).trim().split(" ")[-1] $CurrentName = $currentScheme[1] $CurrentSettings = Powercfg /Q $RawSettings = $CurrentSettings[2..$CurrentSettings.Count] -join [System.Environment]::NewLine #Possible alternative: #$RawSettings = $CurrentQuery[2..$CurrentQuery.Count] | Out-String $SplitSettings = $RawSettings -split '(?:\r?\n){2,}' $SettingsArray = @() foreach($Setting in $SplitSettings){ $IndexCount = -1 $LinedSetting = (($Setting -split '(?:\r?\n)').trim() | ?{$_ -notlike "GUID Alias:*" -and $_ -notlike ""}).Trim() if($SubgroupGuid){ #Remove-Variable SubgroupGuid -ErrorAction SilentlyContinue } if($SubgroupName){ #Remove-Variable SubgroupName -ErrorAction SilentlyContinue } if($PowerSettingGuid){ Remove-Variable PowerSettingGuid -ErrorAction SilentlyContinue } if($MinSettingHex){ Remove-Variable MinSettingHex -ErrorAction SilentlyContinue } if($MinSetting){ Remove-Variable MinSetting -ErrorAction SilentlyContinue } if($MaxSettingHex){ Remove-Variable MaxSettingHex -ErrorAction SilentlyContinue } if($MaxSetting){ Remove-Variable MaxSetting -ErrorAction SilentlyContinue } if($IncrementHex){ Remove-Variable IncrementHex -ErrorAction SilentlyContinue } if($Increment){ Remove-Variable Increment -ErrorAction SilentlyContinue } if($Units){ Remove-Variable Units -ErrorAction SilentlyContinue } if($CurrentACHex){ Remove-Variable CurrentACHex -ErrorAction SilentlyContinue } if($CurrentAC){ Remove-Variable CurrentAC -ErrorAction SilentlyContinue } if($CurrentDCHex){ Remove-Variable CurrentDCHex -ErrorAction SilentlyContinue } if($CurrentDC){ Remove-Variable CurrentDC -ErrorAction SilentlyContinue } foreach($Line in $LinedSetting){ if($Line -like "Subgroup GUID: *"){ $SubgroupGuid = ($Line.split(" ",3)[-1]).split(" ")[0] $SubgroupName = ($Line.split(" ",1)[-1]).split("()")[1] }elseif($Line -like "Power Setting GUID: *"){ $PowerSettingGuid = ($Line.split(" ",4)[-1]).split(" ")[0] $PowerSettingName = ($Line.split(" ",1)[-1]).split("()")[1] }elseif($Line -like "Minimum Possible Setting: *"){ $MinSettingHex = ($Line.split(":")[-1]).trim() $MinSetting = [Convert]::ToString($MinSettingHex,10) }elseif($Line -like "Maximum Possible Setting: *"){ $MaxSettingHex = ($Line.split(":")[-1]).trim() $MaxSetting = [Convert]::ToString($MaxSettingHex,10) }elseif($Line -like "Possible Settings increment: *"){ $IncrementHex = ($Line.split(":")[-1]).trim() $Increment = [Convert]::ToString($IncrementHex,10) }elseif($Line -like "Possible Settings units: *"){ $Units = ($Line.split(":")[-1]).trim() }elseif($Line -like "Current AC Power Setting Index: *"){ $CurrentACHex = ($Line.split(":")[-1]).trim() $CurrentAC = [Convert]::ToString($CurrentACHex,10) }elseif($Line -like "Current DC Power Setting Index: *"){ $CurrentDCHex = ($Line.split(":")[-1]).trim() #($Line.split(" ",3)[-1]).split(" ")[3] $CurrentDC = [Convert]::ToString($CurrentDCHex,10) }elseif($Line -like "Possible Setting Index: *"){ $IndexCount ++ }elseif($Line -like "Possible Setting Friendly Name: *"){ #use Index $IndexName = ($Line.split(":")[-1]).trim() New-Variable -Name IndexTemp$IndexCount -Value $IndexName } } $SettingObj = New-Object psobject if($SubgroupGuid){ $SettingObj | Add-Member NoteProperty SubgroupGuid $SubgroupGuid $SettingObj | Add-Member NoteProperty SubgroupName $SubgroupName }else{ #$SettingObj | Add-Member NoteProperty SubgroupGuid $null #$SettingObj | Add-Member NoteProperty SubgroupName $null } if($PowerSettingGuid){ $SettingObj | Add-Member NoteProperty PowerSettingGuid $PowerSettingGuid $SettingObj | Add-Member NoteProperty PowerSettingName $PowerSettingName }else{ $SettingObj | Add-Member NoteProperty PowerSettingGuid $null $SettingObj | Add-Member NoteProperty PowerSettingName $null } if($MaxSetting){ $SettingObj | Add-Member NoteProperty MaxSetting $MaxSetting }else{ #$SettingObj | Add-Member NoteProperty MaxSetting $null } if($MinSetting){ $SettingObj | Add-Member NoteProperty MinSetting $MinSetting }else{ #$SettingObj | Add-Member NoteProperty MinSetting $null } if($Increment){ $SettingObj | Add-Member NoteProperty Increment $Increment }else{ #$SettingObj | Add-Member NoteProperty Increment $null } if($Units){ $SettingObj | Add-Member NoteProperty Units $Units }else{ #$SettingObj | Add-Member NoteProperty Units $null } if($CurrentAC){ $SettingObj | Add-Member NoteProperty CurrentAC $CurrentAC }else{ $SettingObj | Add-Member NoteProperty CurrentAC $null } if($CurrentDC){ $SettingObj | Add-Member NoteProperty CurrentDC $CurrentDC }else{ $SettingObj | Add-Member NoteProperty CurrentDC $null } $IndexesLoop = -1 while($IndexesLoop -lt $IndexCount){ $IndexesLoop ++ if($CurrentIndex = (Get-Variable IndexTemp$IndexesLoop -ErrorAction SilentlyContinue).Value){ $SettingObj | Add-Member NoteProperty Index$IndexesLoop $CurrentIndex }else{ $SettingObj | Add-Member NoteProperty Index$IndexesLoop $null } } if($SettingObj.Index0){ $IndexACText = "Index$CurrentAC" $CurrentACText = $SettingObj.$IndexACText $IndexDCText = "Index$CurrentDC" $CurrentDCText = $SettingObj.$IndexDCText }else{ $CurrentACText = "$CurrentAC $Units" $CurrentDCText = "$CurrentDC $Units" } $SettingObj | Add-Member NoteProperty ACValue $CurrentACText $SettingObj | Add-Member NoteProperty DCValue $CurrentDCText $SettingsArray += $SettingObj Remove-Variable IndexTemp* -ErrorAction SilentlyContinue } $SettingsArray } function Set-PowercfgSetting{ [cmdletbinding(SupportsShouldProcess,DefaultParameterSetName='Main',ConfirmImpact = 'High')] param( [Parameter(ValueFromPipelineByPropertyName=$false)] [alias("PowerSettingName")] [string]$Setting, [Parameter(ValueFromPipeline=$false)] $Value, [Parameter(ValueFromPipeline=$false)] $Category, [Parameter(ParameterSetName='ACOnly', Mandatory=$false)] [switch]$ACOnly, [Parameter(ParameterSetName='DCOnly', Mandatory=$false)] [switch]$DCOnly, [Parameter(ParameterSetName='ACDC', Mandatory=$false)] [switch]$ACDC, [switch]$Force ) begin{ try{ if(!(Test-Administrator)){ throw "Must be run as Administrator" } }catch{ Write-Error $Global:Error[0] -ErrorAction Stop } #Set Default to AC Only: if($($PSCmdlet.ParameterSetName) -like "Main"){ $ACOnly = $true } if ($Force){ $ConfirmPreference = 'None' } $CurrentScheme = Powercfg -getactivescheme $CurrentScheme = $currentScheme.split("()") $CurrentGuid = ($currentScheme[0]).trim().split(" ")[-1] $CurrentName = $currentScheme[1] $AllSettings = Get-PowercfgSettings $FoundSettings = @() $Values =@() } process{ if($ACOnly){ $Mode = "AC Only" $ChangeAC = $true }elseif($DCOnly){ $Mode = "DC Only" $ChangeDC = $true }elseif($ACDC){ $Mode = "AC & DC" $ChangeAC = $true $ChangeDC = $true } Write-Host "Mode: $Mode" if($Category){ $CatSettings = $AllSettings | ?{$_.SubgroupName -like "*$Category*"} if($CatSettings){ $AllSettings = @() $AllSettings += $CatSettings } } if($Setting){ $MatchedSettings =@() $MatchedSettings += $AllSettings | ?{$_.PowerSettingName -like "*$Setting*"} }else{ $MatchedSettings += $AllSettings } $FoundSettings += $MatchedSettings if($Value.count){ $Values += $Value } } end{ while($FoundSettings.count -gt 1){ Write-Host "Select Setting:" $FoundSettings = $FoundSettings | Invoke-MultiChoice -Property PowerSettingName } $ChosenSetting = $FoundSettings $ChosenString = $ChosenSetting | FT SubgroupName,PowerSettingName,ACValue,DCValue | Out-String Write-Host "Chosen Setting:" Write-Host "$ChosenString" if($ChosenSetting.MaxSetting){ $ValidateString = "Integers between $($ChosenSetting.MinSetting) and $($ChosenSetting.MaxSetting), Units: $($ChosenSetting.Units)" $ChosenMin = $ChosenSetting.MinSetting $ChosenMax = $ChosenSetting.MaxSetting } if($ChosenSetting.Index0){ $Indexes = ($ChosenSetting |Get-Member -Name Index*).Name $IndexArray = @() $IndexCount = -1 foreach($Index in $Indexes){ $IndexCount ++ $IndexObject = New-Object PSObject $IndexObject | Add-Member ID $IndexCount $IndexObject | Add-Member Name $ChosenSetting."Index$IndexCount" $IndexArray += $IndexObject } $ValidateArray = $IndexArray | FT -Hide |out-string $ValidateString = "Integers between 0 and $IndexCount matching array options:" $ChosenMin = 0 $ChosenMax = $IndexCount } Write-Host "Validation: $ValidateString" if($ValidateArray){ Write-Host "$ValidateArray" } $Values = $Values | sort | Select -Unique while($Values.count -gt 1){ $Values = $Values | Invoke-MultiChoice } while($Values -lt $ChosenMin -or $Values -gt $ChosenMax){ [int32]$Values = Read-Host "Enter Value $ChosenMin-$ChosenMax" } $ChosenValue = $Values if($ValidateArray){ $ChosenText = $ChosenSetting."Index$ChosenValue" }else{ $ChosenText = "$ChosenValue" } Write-Host "Selected Value: $ChosenValue" if ($PSCmdlet.ShouldProcess($ChosenSetting.PowerSettingName,"Set $Mode Value to: $ChosenText $($ChosenSetting.Units)")){ #Set powercfg if($ChangeDC){ powercfg /SETDCVALUEINDEX $CurrentGuid $ChosenSetting.SubgroupGuid $ChosenSetting.PowerSettingGuid $ChosenValue } if($ChangeAC){ powercfg /SETACVALUEINDEX $CurrentGuid $ChosenSetting.SubgroupGuid $ChosenSetting.PowerSettingGuid $ChosenValue } Write-Host "Set: $($Mode): '$($ChosenSetting.PowerSettingName)' to '$ChosenText' $($ChosenSetting.Units)" } #Check: Write-Host "Updated Settings:" Get-PowercfgSettings| ?{$_.PowerSettingName -like $ChosenSetting.PowerSettingName} | FT SubgroupName,PowerSettingName,ACValue,DCValue #Until Formatfiles } } ### <# Usage Examples: Get-PowercfgSettings | Select SubgroupName,PowerSettingName,ACValue,DCValue #Until Formatfiles $SettingsToChangeAC = ConvertFrom-CSV -delim ';' -Input @" "Setting"; "Value" "Turn off hard disk after"; 120 "Hibernate after"; 0 "Sleep after"; 0 "System cooling policy"; 1 "Minimum processor state"; 100 "@ foreach($STC in $SettingsToChangeAC){ Set-PowercfgSetting -Setting $STC.Setting -Value $STC.Value -Force } #> Write-Host "Functions available:" -ForegroundColor Magenta Write-Host "Get-PowercfgSettings" -NoNewLine Write-Host " (List all Power Settings)" -ForegroundColor Cyan Write-Host "Set-PowercfgSetting" -NoNewLine Write-Host " (Change a setting, prompted for selections as required, requires Admin)" -ForegroundColor Cyan |