需求

防止我在梦中惊醒,一怒之下整了这个脚本

实现

  1. 实现锁屏静音🔇,解锁恢复
  2. 锁屏前就是静音状态,则解锁保持静音🔇
  3. 接住AudioDeviceCmdlets模块,运行几乎无压力

代码

把下面代码用自带记事本保存,文件名(包括扩展名)改成 SetupMuteOnLock.ps1 并使用管理员权限运行。

# 需要以管理员权限运行
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host "请以管理员权限运行此脚本!" -ForegroundColor Red
    Start-Sleep -Seconds 3
    exit
}

Write-Host "正在设置锁屏自动静音功能..." -ForegroundColor Green

# 创建脚本目录
$scriptDir = "$env:USERPROFILE\LockScreenMuteScripts"
if (-not (Test-Path -Path $scriptDir)) {
    New-Item -Path $scriptDir -ItemType Directory | Out-Null
}

# 检查AudioDeviceCmdlets模块是否安装
$moduleInstalled = Get-Module -ListAvailable -Name AudioDeviceCmdlets
if (-not $moduleInstalled) {
    Write-Host "安装AudioDeviceCmdlets模块..." -ForegroundColor Yellow
    Install-Module -Name AudioDeviceCmdlets -Force -Scope CurrentUser
    Write-Host "AudioDeviceCmdlets模块安装成功!" -ForegroundColor Green
}

# 创建静音脚本 (使用VBS包装以隐藏PowerShell窗口)
$mutePath = "$scriptDir\Mute.ps1"
@"
# 保存当前音量状态
Import-Module AudioDeviceCmdlets

# 获取当前状态
`$isMuted = Get-AudioDevice -PlaybackMute

# 保存状态到文件
"`$isMuted" | Out-File -FilePath "$env:USERPROFILE\volume_state.txt" -Force

# 设置静音
Set-AudioDevice -PlaybackMute `$true
"@ | Out-File -FilePath $mutePath -Encoding utf8

# 创建取消静音脚本 (使用VBS包装以隐藏PowerShell窗口)
$unmutePath = "$scriptDir\Unmute.ps1"
@"
# 恢复之前的音量状态
Import-Module AudioDeviceCmdlets

# 读取保存的状态
if (Test-Path -Path "$env:USERPROFILE\volume_state.txt") {
    `$savedState = Get-Content -Path "$env:USERPROFILE\volume_state.txt"
    `$wasMuted = [System.Convert]::ToBoolean(`$savedState)
  
    # 如果之前没有静音,则恢复
    if (-not `$wasMuted) {
        Set-AudioDevice -PlaybackMute `$false
    }
}
"@ | Out-File -FilePath $unmutePath -Encoding utf8

# 创建VBS包装脚本(完全隐藏窗口)
$muteVbsPath = "$scriptDir\Mute.vbs"
@"
Set objShell = CreateObject("Wscript.Shell")
command = "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -NonInteractive -File ""$mutePath"""
objShell.Run command, 0, False
"@ | Out-File -FilePath $muteVbsPath -Encoding ASCII

$unmuteVbsPath = "$scriptDir\Unmute.vbs"
@"
Set objShell = CreateObject("Wscript.Shell")
command = "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -NonInteractive -File ""$unmutePath"""
objShell.Run command, 0, False
"@ | Out-File -FilePath $unmuteVbsPath -Encoding ASCII

# 设置任务计划
$lockTaskName = "LockScreenMute"
$unlockTaskName = "UnlockScreenUnmute"

# 删除已有任务(如果存在)
schtasks /Query /TN $lockTaskName 2>$null
if ($LASTEXITCODE -eq 0) {
    schtasks /Delete /TN $lockTaskName /F | Out-Null
}

schtasks /Query /TN $unlockTaskName 2>$null
if ($LASTEXITCODE -eq 0) {
    schtasks /Delete /TN $unlockTaskName /F | Out-Null
}

# 创建自定义XML触发器(会话锁定)
$xmlTask = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2023-01-01T00:00:00.0000000</Date>
    <Author>$env:USERNAME</Author>
    <Description>锁屏时自动静音</Description>
  </RegistrationInfo>
  <Triggers>
    <SessionStateChangeTrigger>
      <Enabled>true</Enabled>
      <StateChange>SessionLock</StateChange>
    </SessionStateChangeTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>$env:USERDOMAIN\$env:USERNAME</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>wscript.exe</Command>
      <Arguments>"$muteVbsPath"</Arguments>
    </Exec>
  </Actions>
</Task>
"@

$xmlPath = "$scriptDir\LockScreenMute.xml"
$xmlTask | Out-File -FilePath $xmlPath -Encoding unicode

# 创建自定义XML触发器(会话解锁)
$xmlUnlockTask = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2023-01-01T00:00:00.0000000</Date>
    <Author>$env:USERNAME</Author>
    <Description>解锁时恢复音量</Description>
  </RegistrationInfo>
  <Triggers>
    <SessionStateChangeTrigger>
      <Enabled>true</Enabled>
      <StateChange>SessionUnlock</StateChange>
    </SessionStateChangeTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>$env:USERDOMAIN\$env:USERNAME</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>wscript.exe</Command>
      <Arguments>"$unmuteVbsPath"</Arguments>
    </Exec>
  </Actions>
</Task>
"@

$xmlUnlockPath = "$scriptDir\UnlockScreenUnmute.xml"
$xmlUnlockTask | Out-File -FilePath $xmlUnlockPath -Encoding unicode

# 注册任务
Write-Host "注册任务计划..." -ForegroundColor Yellow
& schtasks.exe /Create /TN $lockTaskName /XML $xmlPath /F
& schtasks.exe /Create /TN $unlockTaskName /XML $xmlUnlockPath /F

# 设置PowerShell执行策略
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force | Out-Null

# 手动测试脚本
Write-Host "`n正在测试静音功能..." -ForegroundColor Yellow
& wscript.exe "$muteVbsPath"
Write-Host "系统已静音,按任意键继续测试..." -ForegroundColor Cyan
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Write-Host "正在测试取消静音功能..." -ForegroundColor Yellow
& wscript.exe "$unmuteVbsPath"
Write-Host "已恢复原音量状态" -ForegroundColor Cyan

Write-Host "`n安装完成!" -ForegroundColor Green
Write-Host "现在当你锁屏时,系统将自动静音,解锁时将恢复原来的音量状态。" -ForegroundColor Cyan
Write-Host "脚本文件位于:$scriptDir" -ForegroundColor Cyan
Write-Host "`n如需卸载,请在任务计划程序中删除名为 '$lockTaskName' 和 '$unlockTaskName' 的任务。" -ForegroundColor Yellow

Write-Host "`n按任意键退出..." -ForegroundColor Gray
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
最后修改:2025-07-16
如果觉得我的文章有意思,欢迎赞赏,我会努力创造更好的文章!