【问题标题】:Powershell Set Lid Close ActionPowershell 设置盖子关闭操作
【发布时间】:2013-03-05 13:15:14
【问题描述】:

我想自动设置 Windows 7 在我的工作笔记本电脑上合上盖子时执行的操作,因为每次我登录时都会通过 GPO 重置。

我知道我可以在批处理脚本中使用 powercfg 命令来实现:

powercfg -setacvalueindex 5ca83367-6e45-459f-a27b-476b1d01c936 0
powercfg -setdcvalueindex 5ca83367-6e45-459f-a27b-476b1d01c936 0

但是,这是尝试学习一些 powershell 的好借口。我的第一次尝试需要 10 多秒才能运行。

我如何在运行时和代码的清洁度方面改进以下内容。解决以下问题的惯用 powershell 方式是什么?

$DO_NOTHING = 0

$activePowerPlan = Get-WmiObject -Namespace "root\cimv2\power" Win32_PowerPlan | where {$_.IsActive}
$rawPowerPlanID = $activePowerPlan | select -Property InstanceID
$rawPowerPlanID -match '\\({.*})}'
$powerPlanID = $matches[1]

# The .GetRelated() method is an inefficient approach, i'm looking for a needle and this haystack is too big. Can i go directly to the object instead of searching?
$lidCloseActionOnACPower = $activePowerPlan.GetRelated("win32_powersettingdataindex") | where {$_.InstanceID -eq "Microsoft:PowerSettingDataIndex\$powerPlanID\AC\{5ca83367-6e45-459f-a27b-476b1d01c936}"}
$lidCloseActionOnBattery = $activePowerPlan.GetRelated("win32_powersettingdataindex") | where {$_.InstanceID -eq "Microsoft:PowerSettingDataIndex\$powerPlanID\DC\{5ca83367-6e45-459f-a27b-476b1d01c936}"}

$lidCloseActionOnACPower | select -Property SettingIndexValue
$lidCloseActionOnACPower.SettingIndexValue = $DO_NOTHING
$lidCloseActionOnACPower.put()

$lidCloseActionOnBattery | select -Property SettingIndexValue
$lidCloseActionOnBattery.SettingIndexValue = $DO_NOTHING
$lidCloseActionOnBattery.put()

【问题讨论】:

    标签: windows powershell wmi


    【解决方案1】:

    试试 WMI 加速器:

    $class = ([wmi] '\root\cimv2\power:Win32_PowerSettingDataIndex.InstanceID="Microsoft:PowerSettingDataIndex\\{8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c}\\DC\\{5ca83367-6e45-459f-a27b-476b1d01c936}"')
    $class.SettingIndexValue = 0
    $class.Put()
    

    【讨论】:

      【解决方案2】:

      老实说,我看不出有什么理由不应该使用简单有效的工具... ;) 无论如何:当使用 WMI 时,尽可能多地向左过滤通常是个好主意。在这里应该没什么区别,但有时差异很大。这就是我使用 WMI 的方式:

      $Name = @{
          Namespace = 'root\cimv2\power'
      }
      $ID = (Get-WmiObject @Name Win32_PowerPlan -Filter "IsActive = TRUE") -replace '.*(\{.*})"', '$1'
      $Lid = '{5ca83367-6e45-459f-a27b-476b1d01c936}'
      Get-WmiObject @Name Win32_PowerSettingDataIndex -Filter "InstanceId LIKE '%$Id\\%C\\$Lid'" | 
          Set-WmiInstance -Arguments @{ SettingIndexValue = 0 }
      

      可能有更高级的 WQL 查询更好的方法,这与您所做的几乎相同,只是稍作修改。

      【讨论】:

      • 看起来他甚至不需要查询powersettingdataindex,只需powerplan。
      【解决方案3】:

      我想做同样的事情却遇到完全相同的问题。最后,我发现您需要在命令行中插入优于您要修改的注册表项:

      powercfg -setacvalueindex 5ca83367-6e45-459f-a27b-476b1d01c936 0
      powercfg -setdcvalueindex 5ca83367-6e45-459f-a27b-476b1d01c936 0
      

      应该变成:

      powercfg -setacvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e 4f971e89-eebd-4455-a8de-9e59040e7347 5ca83367-6e45-459f-a27b-476b1d01c936 0
      powercfg -setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e 4f971e89-eebd-4455-a8de-9e59040e7347 5ca83367-6e45-459f-a27b-476b1d01c936 0
      

      只需将其放入 BAT 文件中即可开始使用!

      【讨论】:

        【解决方案4】:

        我在Quickly change the "lid" power setting on your laptop 上找到了这个脚本。要求同意使用条款。适用于 W10。

        @echo off 
        set debug=1 
        ::************************* 
        :: Script Name: lid.cmd 
        :: author: Stephen D Arsenault 
        :: Creation Date: 2013-september-07 
        :: Modified Date: 2013-september-07 
        :: Description:    Changes the lid action to sleep or do nothing 
        :: parameters:     - on: sets lid action to do nothing 
        ::        - off: sets lid action to sleep 
        ::************************* 
         
        echo Getting current scheme GUID 
        ::store the output of powercfg /getactivescheme in %cfg% 
        for /f "tokens=* USEBACKQ" %%a in (`powercfg /getactivescheme`) do @set cfg=%%a 
        if %debug%==1 echo Current %cfg% 
         
        ::trim power config output to get GUID 
        set trimcfg=%cfg:~19,36% 
        if %debug%==1 echo %trimcfg% 
         
        ::accepts arguments 
        if %1==off set newVal=001 
        if %1==OFF set newVal=001 
        if %1==on set newVal=000 
        if %1==ON set newVal=000 
         
        ::make power scheme change 
        powercfg /setdcvalueindex %trimcfg% 4f971e89-eebd-4455-a8de-9e59040e7347 5ca83367-6e45-459f-a27b- 
         
        476b1d01c936 %newVal% >nul 2>&1 
         
        powercfg /setacvalueindex %trimcfg% 4f971e89-eebd-4455-a8de-9e59040e7347 5ca83367-6e45-459f-a27b- 
         
        476b1d01c936 %newVal% >nul 2>&1 
         
        if %errorlevel%==1 echo "Invalid Parameters" 
        if %errorlevel%==1 pause 
        if %errorlevel%==1 echo %date% %time% Invalid Parameters: %1 >>C:\tools\lid.log 
        echo %date% %time% %1 >>C:\tools\lid.log 
         
        ::apply changes 
        powercfg /s %trimcfg%
        

        注意:该脚本包含两个对c:\tools 的硬编码引用。这些引用仅用于记录,因此您可以安全地将它们注释掉或将它们修改为您的文件结构。

        【讨论】:

          【解决方案5】:

          这部分 PowerShell 确实会更改注册表设置,但不会更改我的笔记本电脑在合上盖子时的行为。使用 powercfg 与此 WMI 对象执行相同的操作。

          显然,注册表子组 PowerButtons and Lid 有 2 组不同的注册表项。

          此脚本和powercfg 中的相同命令,将Power Options >> Advanced Settings 中的此子组更改为Do Nothing(或Sleep,或Hibernate,或您设置的0 - 3 中的任何选项编号) ,但在Change what the power buttons doChange what closing the lid does 的实际控制面板设置中不受影响。控制面板中的设置实际上决定了操作,至少对于这个子组而言。

          如果我使用powercfg 或与上面编写的类似的PS 脚本,我实际上可以Change Plan Settings 获得所需的行为来调暗显示器(或其他)。我只是找不到任何适合Power Buttons and Lid 子组的东西。

          【讨论】:

            【解决方案6】:

            我在 Windows 8.1 中看到的是,当针对电源方案更改盖子操作时,该电源方案必须既是活动电源方案又是首选电源方案。 PowerCfg可以设置活动电源方案,注册表设置首选电源方案。

            这是一个用于更改它们的 Powershell 脚本和盖子操作:

            #Enable High performance
            $powerScheme = "High performance"
            
            #Find selected power scheme guid
            $guidRegex = "(\{){0,1}[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}(\}){0,1}"
            [regex]$regex = $guidRegex
            $guid = ($regex.Matches((PowerCfg /LIST | where {$_ -like "*$powerScheme*"}).ToString())).Value
            
            #Change preferred scheme
            $regGuid = "{025A5937-A6BE-4686-A844-36FE4BEC8B6D}"
            $currentPreferredScheme = Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\ControlPanel\NameSpace\$regGuid -Name PreferredPlan 
            if ($currentPreferredScheme.PreferredPlan -ne $guid) {
                Set-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\ControlPanel\NameSpace\$regGuid -Name PreferredPlan -Value $guid
                Write-Host -ForegroundColor Green "Preferred scheme successfully changed. Preferred scheme is now '$powerScheme'." 
            } else {
                Write-Host -ForegroundColor Yellow "Preferred scheme does not need to be changed. Preferred scheme is '$powerScheme'." 
            }
            
            #Change active scheme
            $currentActiveScheme = PowerCfg /GETACTIVESCHEME
            if ($currentActiveScheme | where {$_ -notlike "*$guid*"}) {
                PowerCfg /SETACTIVE $guid
                Write-Host -ForegroundColor Green "Power scheme successfully changed. Current scheme is now '$powerScheme'." 
            } else {
                Write-Host -ForegroundColor Yellow "Power scheme does not need to be changed. Current scheme is '$powerScheme'." 
            }
            
            #Do not sleep when closing lid on AC
            PowerCfg /SETACVALUEINDEX $guid SUB_BUTTONS LIDACTION 000
            Write-Host -ForegroundColor Green "No action when closing lid on AC."
            

            【讨论】:

            • 谢谢。这是救命稻草,我想知道为什么其他答案都没有提到该方案必须是盖子关闭操作生效的首选方案。
            【解决方案7】:

            带有所有别名的Powercfg:

            powercfg -setacvalueindex scheme_current sub_buttons pbuttonaction 0
            

            【讨论】:

              【解决方案8】:

              我只是试图在当前的 Windows 上复制它,而旧的解决方案将不再起作用(CIM 中不提供“激活”方法,并且尝试使用激活方法应用来自 WMI 的更改会引发错误该方法未定义)

              我最终用来检查当前 PowerPlan (CIM) 上的设置是否正确的代码以及应用更改的最简单方法似乎是直接使用 powercfg.exe

              未注释的powercfg 行是别名,因为此设置有别名,但并非所有设置都有别名。

              如果您不知道您想要的子组或设置的 GUID,您应该可以使用很长的 powercfg /Qh 检查它们,您可能希望在文本文件中查看。

              这将运行报告并在文本文件中打开它 powercfg /Qh > %temp%\CurrentPower Settings.txt && %temp%\CurrentPowerSettings.txt

              下面的这个脚本只是将设置应用于当前的、活动的电源计划——但如果你直接知道是哪个

              $DesiredValue = 0
              $SettingSubGroupID = '4f971e89-eebd-4455-a8de-9e59040e7347'
              $SettingGUID       = '5ca83367-6e45-459f-a27b-476b1d01c936'
                  
              # Select Current Power Plan
              $currentPLan = Get-CimInstance -namespace "root\cimv2\power" -class Win32_powerplan | where {$_.IsActive} 
              $schemeID= $currentPLan.InstanceID -replace "^Microsoft:PowerPlan\\{(.*?)}$",'$1'
                  
              # Apply Settings to Specific Power Plan by GUID
              # $specificPowerPlanID = '8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c'
              # $currentPlan = Get-CimInstance -namespace "root\cimv2\power" -class Win32_powerplan | where {$_.InstanceID -match $specificPowerPlanID} 
              # $schemeID= $currentPLan.InstanceID -replace "^Microsoft:PowerPlan\\{(.*?)}$",'$1'
              
              # Optionally Activate this specific Power Plan
              # powercfg -SetActive $specificPowerPlanID
              
              $currPLanLidCLoseSettings = Get-CimAssociatedInstance -InputObject $currentPLan -ResultClassName 'win32_powersettingdataindex' | where {$_.InstanceID -match $SettingGUID} 
              $improperSettings = $currPLanLidCLoseSettings | where {$_.settingIndexValue -ne $DesiredValue}
              
              If ($improperSettings) {
                  Write-Verbose -Verbose "Found $(@($improperSettings).Count) settings in current power plan that do not match. Fixing"
                  # Aliases are taken from 'powercfg /Aliases'
                  # SubGroup GUID Alias SUB_BUTTONS = 4f971e89-eebd-4455-a8de-9e59040e7347 
                  # SubGroup GUID Alias LIDACTION   = 5ca83367-6e45-459f-a27b-476b1d01c936 
                  
                  powercfg -SETACVALUEINDEX $schemeID SUB_BUTTONS LIDACTION $DesiredValue
                  powercfg -SETDCVALUEINDEX $schemeID SUB_BUTTONS LIDACTION $DesiredValue
                  # powercfg -SETACVALUEINDEX $schemeID $SettingSubGroupID $SettingGUID$SettingGUID $DesiredValue
                  # powercfg -SETDCVALUEINDEX $schemeID $SettingSubGroupID $SettingGUID $DesiredValue
                  
                  Write-Verbose -Verbose "New Values are below" 
                  Get-CimAssociatedInstance -InputObject $currentPLan -ResultClassName 'win32_powersettingdataindex' | where {$_.InstanceID -match $SettingGUID} 
                  
              } 
              else {
                  Write-Verbose -Verbose "All settings are already correct" 
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-03-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多