safe-shutdown.ps1
· 5.9 KiB · PowerShell
Orginalformat
# 安全关机脚本
# 需要管理员权限运行
# 检查是否以管理员身份运行
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "请以管理员身份运行此脚本!" -ForegroundColor Red
Pause
# 退出当前非管理员进程
exit 1
}
Write-Host "开始执行安全关机流程..." -ForegroundColor Green
# 配置参数
$virtualBoxVMs = @("CentOS", "fnOS") # 替换为您的虚拟机名称
$podmanContainers = @("filecodebox") # 替换为您的容器名称
$vboxManagePath = "C:\Users\NAS\Programs\VirtualBox\VBoxManage.exe"
# 1. 关闭VirtualBox虚拟机
Write-Host "`n1. 检查并关闭VirtualBox虚拟机..." -ForegroundColor Yellow
if (Test-Path $vboxManagePath) {
foreach ($vm in $virtualBoxVMs) {
Write-Host "检查虚拟机: $vm" -ForegroundColor Cyan
# 检查虚拟机状态
$vmStatus = & $vboxManagePath showvminfo $vm --machinereadable 2>$null | Select-String "VMState="
if ($vmStatus) {
$state = $vmStatus -replace 'VMState="|"', ''
Write-Host "虚拟机 $vm 状态: $state"
if ($state -eq "running") {
Write-Host "正在关闭虚拟机: $vm" -ForegroundColor Yellow
& $vboxManagePath controlvm $vm acpipowerbutton
# 等待虚拟机优雅关闭(最多30秒)
$timeout = 30
$counter = 0
while (($state -eq "running") -and ($counter -lt $timeout)) {
Start-Sleep -Seconds 1
$counter++
$vmStatus = & $vboxManagePath showvminfo $vm --machinereadable 2>$null | Select-String "VMState="
if ($vmStatus) {
$state = $vmStatus -replace 'VMState="|"', ''
}
}
if ($state -eq "running") {
Write-Host "强制关闭虚拟机: $vm" -ForegroundColor Red
& $vboxManagePath controlvm $vm poweroff
} else {
Write-Host "虚拟机 $vm 已成功关闭" -ForegroundColor Green
}
} else {
Write-Host "虚拟机 $vm 未运行,跳过关闭" -ForegroundColor Gray
}
} else {
Write-Host "未找到虚拟机: $vm" -ForegroundColor Gray
}
}
} else {
Write-Host "未找到VirtualBox (路径: $vboxManagePath),跳过虚拟机关闭步骤" -ForegroundColor Gray
}
# 2. 关闭Podman容器和服务
Write-Host "`n2. 检查并关闭Podman容器和服务..." -ForegroundColor Yellow
# 关闭Podman容器
if (Get-Command "podman" -ErrorAction SilentlyContinue) {
foreach ($container in $podmanContainers) {
Write-Host "检查容器: $container" -ForegroundColor Cyan
# 检查容器是否存在且运行中
$containerInfo = podman ps -a --filter "name=$container" --format "{{.Names}}:{{.State}}"
if ($containerInfo) {
$containerState = $containerInfo.Split(':')[1]
Write-Host "容器 $container 状态: $containerState"
if ($containerState -eq "running") {
Write-Host "正在停止容器: $container" -ForegroundColor Yellow
podman stop $container
# 检查停止是否成功
Start-Sleep -Seconds 2
$newState = (podman ps -a --filter "name=$container" --format "{{.State}}")
if ($newState -eq "exited") {
Write-Host "容器 $container 已成功停止" -ForegroundColor Green
} else {
Write-Host "容器 $container 停止失败" -ForegroundColor Red
}
} else {
Write-Host "容器 $container 未运行,跳过停止" -ForegroundColor Gray
}
} else {
Write-Host "未找到容器: $container" -ForegroundColor Gray
}
}
# 停止所有正在运行的容器(额外安全措施)
Write-Host "检查是否有其他运行中的容器..." -ForegroundColor Cyan
$runningContainers = podman ps -q --filter "status=running"
if ($runningContainers) {
Write-Host "停止所有运行中的容器..." -ForegroundColor Yellow
podman stop $runningContainers
}
# 关闭Podman服务(如果使用Podman Machine)
Write-Host "检查Podman服务状态..." -ForegroundColor Cyan
$podmanService = Get-Service -Name "Podman Machine" -ErrorAction SilentlyContinue
if ($podmanService) {
if ($podmanService.Status -eq "Running") {
Write-Host "正在停止Podman服务..." -ForegroundColor Yellow
Stop-Service -Name "Podman Machine" -Force
Write-Host "Podman服务已停止" -ForegroundColor Green
} else {
Write-Host "Podman服务未运行" -ForegroundColor Gray
}
}
} else {
Write-Host "未找到Podman,跳过容器关闭步骤" -ForegroundColor Gray
}
# 3. 执行netsh winsock reset
Write-Host "`n3. 执行netsh winsock reset..." -ForegroundColor Yellow
try {
netsh winsock reset
Write-Host "netsh winsock reset 执行成功" -ForegroundColor Green
} catch {
Write-Host "执行netsh winsock reset时出错: $_" -ForegroundColor Red
}
Write-Host "`n安全关机流程完成!" -ForegroundColor Green
Write-Host "您现在可以安全地关闭计算机。" -ForegroundColor Green
# 可选:自动关机(取消注释以下行以启用自动关机)
# Write-Host "系统将在10秒后自动关机..." -ForegroundColor Yellow
# Start-Sleep -Seconds 10
# Stop-Computer -Force
# 暂停以便查看输出结果
Write-Host "`n按任意键退出..." -ForegroundColor Gray
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
| 1 | # 安全关机脚本 |
| 2 | # 需要管理员权限运行 |
| 3 | |
| 4 | # 检查是否以管理员身份运行 |
| 5 | if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { |
| 6 | Write-Host "请以管理员身份运行此脚本!" -ForegroundColor Red |
| 7 | |
| 8 | Pause |
| 9 | # 退出当前非管理员进程 |
| 10 | exit 1 |
| 11 | } |
| 12 | |
| 13 | Write-Host "开始执行安全关机流程..." -ForegroundColor Green |
| 14 | |
| 15 | # 配置参数 |
| 16 | $virtualBoxVMs = @("CentOS", "fnOS") # 替换为您的虚拟机名称 |
| 17 | $podmanContainers = @("filecodebox") # 替换为您的容器名称 |
| 18 | $vboxManagePath = "C:\Users\NAS\Programs\VirtualBox\VBoxManage.exe" |
| 19 | |
| 20 | # 1. 关闭VirtualBox虚拟机 |
| 21 | Write-Host "`n1. 检查并关闭VirtualBox虚拟机..." -ForegroundColor Yellow |
| 22 | |
| 23 | if (Test-Path $vboxManagePath) { |
| 24 | foreach ($vm in $virtualBoxVMs) { |
| 25 | Write-Host "检查虚拟机: $vm" -ForegroundColor Cyan |
| 26 | |
| 27 | # 检查虚拟机状态 |
| 28 | $vmStatus = & $vboxManagePath showvminfo $vm --machinereadable 2>$null | Select-String "VMState=" |
| 29 | |
| 30 | if ($vmStatus) { |
| 31 | $state = $vmStatus -replace 'VMState="|"', '' |
| 32 | Write-Host "虚拟机 $vm 状态: $state" |
| 33 | |
| 34 | if ($state -eq "running") { |
| 35 | Write-Host "正在关闭虚拟机: $vm" -ForegroundColor Yellow |
| 36 | & $vboxManagePath controlvm $vm acpipowerbutton |
| 37 | |
| 38 | # 等待虚拟机优雅关闭(最多30秒) |
| 39 | $timeout = 30 |
| 40 | $counter = 0 |
| 41 | while (($state -eq "running") -and ($counter -lt $timeout)) { |
| 42 | Start-Sleep -Seconds 1 |
| 43 | $counter++ |
| 44 | $vmStatus = & $vboxManagePath showvminfo $vm --machinereadable 2>$null | Select-String "VMState=" |
| 45 | if ($vmStatus) { |
| 46 | $state = $vmStatus -replace 'VMState="|"', '' |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | if ($state -eq "running") { |
| 51 | Write-Host "强制关闭虚拟机: $vm" -ForegroundColor Red |
| 52 | & $vboxManagePath controlvm $vm poweroff |
| 53 | } else { |
| 54 | Write-Host "虚拟机 $vm 已成功关闭" -ForegroundColor Green |
| 55 | } |
| 56 | } else { |
| 57 | Write-Host "虚拟机 $vm 未运行,跳过关闭" -ForegroundColor Gray |
| 58 | } |
| 59 | } else { |
| 60 | Write-Host "未找到虚拟机: $vm" -ForegroundColor Gray |
| 61 | } |
| 62 | } |
| 63 | } else { |
| 64 | Write-Host "未找到VirtualBox (路径: $vboxManagePath),跳过虚拟机关闭步骤" -ForegroundColor Gray |
| 65 | } |
| 66 | |
| 67 | # 2. 关闭Podman容器和服务 |
| 68 | Write-Host "`n2. 检查并关闭Podman容器和服务..." -ForegroundColor Yellow |
| 69 | |
| 70 | # 关闭Podman容器 |
| 71 | if (Get-Command "podman" -ErrorAction SilentlyContinue) { |
| 72 | foreach ($container in $podmanContainers) { |
| 73 | Write-Host "检查容器: $container" -ForegroundColor Cyan |
| 74 | |
| 75 | # 检查容器是否存在且运行中 |
| 76 | $containerInfo = podman ps -a --filter "name=$container" --format "{{.Names}}:{{.State}}" |
| 77 | |
| 78 | if ($containerInfo) { |
| 79 | $containerState = $containerInfo.Split(':')[1] |
| 80 | Write-Host "容器 $container 状态: $containerState" |
| 81 | |
| 82 | if ($containerState -eq "running") { |
| 83 | Write-Host "正在停止容器: $container" -ForegroundColor Yellow |
| 84 | podman stop $container |
| 85 | |
| 86 | # 检查停止是否成功 |
| 87 | Start-Sleep -Seconds 2 |
| 88 | $newState = (podman ps -a --filter "name=$container" --format "{{.State}}") |
| 89 | if ($newState -eq "exited") { |
| 90 | Write-Host "容器 $container 已成功停止" -ForegroundColor Green |
| 91 | } else { |
| 92 | Write-Host "容器 $container 停止失败" -ForegroundColor Red |
| 93 | } |
| 94 | } else { |
| 95 | Write-Host "容器 $container 未运行,跳过停止" -ForegroundColor Gray |
| 96 | } |
| 97 | } else { |
| 98 | Write-Host "未找到容器: $container" -ForegroundColor Gray |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | # 停止所有正在运行的容器(额外安全措施) |
| 103 | Write-Host "检查是否有其他运行中的容器..." -ForegroundColor Cyan |
| 104 | $runningContainers = podman ps -q --filter "status=running" |
| 105 | if ($runningContainers) { |
| 106 | Write-Host "停止所有运行中的容器..." -ForegroundColor Yellow |
| 107 | podman stop $runningContainers |
| 108 | } |
| 109 | |
| 110 | # 关闭Podman服务(如果使用Podman Machine) |
| 111 | Write-Host "检查Podman服务状态..." -ForegroundColor Cyan |
| 112 | $podmanService = Get-Service -Name "Podman Machine" -ErrorAction SilentlyContinue |
| 113 | if ($podmanService) { |
| 114 | if ($podmanService.Status -eq "Running") { |
| 115 | Write-Host "正在停止Podman服务..." -ForegroundColor Yellow |
| 116 | Stop-Service -Name "Podman Machine" -Force |
| 117 | Write-Host "Podman服务已停止" -ForegroundColor Green |
| 118 | } else { |
| 119 | Write-Host "Podman服务未运行" -ForegroundColor Gray |
| 120 | } |
| 121 | } |
| 122 | } else { |
| 123 | Write-Host "未找到Podman,跳过容器关闭步骤" -ForegroundColor Gray |
| 124 | } |
| 125 | |
| 126 | # 3. 执行netsh winsock reset |
| 127 | Write-Host "`n3. 执行netsh winsock reset..." -ForegroundColor Yellow |
| 128 | try { |
| 129 | netsh winsock reset |
| 130 | Write-Host "netsh winsock reset 执行成功" -ForegroundColor Green |
| 131 | } catch { |
| 132 | Write-Host "执行netsh winsock reset时出错: $_" -ForegroundColor Red |
| 133 | } |
| 134 | |
| 135 | Write-Host "`n安全关机流程完成!" -ForegroundColor Green |
| 136 | Write-Host "您现在可以安全地关闭计算机。" -ForegroundColor Green |
| 137 | |
| 138 | # 可选:自动关机(取消注释以下行以启用自动关机) |
| 139 | # Write-Host "系统将在10秒后自动关机..." -ForegroundColor Yellow |
| 140 | # Start-Sleep -Seconds 10 |
| 141 | # Stop-Computer -Force |
| 142 | |
| 143 | # 暂停以便查看输出结果 |
| 144 | Write-Host "`n按任意键退出..." -ForegroundColor Gray |
| 145 | $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") |