有没有更好的方法来使用 PowerShell 实现服务的开/关
Posted
技术标签:
【中文标题】有没有更好的方法来使用 PowerShell 实现服务的开/关【英文标题】:Is there a better way to achieve the on/off of the services using PowerShell 【发布时间】:2022-01-09 12:58:53 【问题描述】:我创建了一个脚本来停止和运行我们在其中一台服务器上运行的一些自定义服务。我想在下午 5 点(17:00)停止服务,然后在凌晨 2 点(02:00)启动它们。但是周五我希望服务运行到下午 5 点以后,周六凌晨 1 点就停止了。
我写了下面的脚本。我还是 PowerShell 脚本的新手。我使用 switch case 来执行这些功能,但我认为必须有更好的方法来实现这一点。
# PowerShell script to stop and start services.
# Variable assignement
$OnOffSwitch = Get-Date -Format 'dddd_HH:mm';
$ServiceNames = @('CAPS8','CAPS9'); # Array to store service names.
function serivcesOff
# Checks the all the service in the above $serviceNames.
foreach ($SeviceName in $ServiceNames)
# Check for service status if stopped this will start it and goes throug the loop again.
# until status matches running.
if ((Get-Service -Name $ServiceName).Status -eq "Running")
do
Start-Service $ServiceName
Start-Sleep -Seconds 20
until ((Get-Service $ServiceName).Status -eq "Stopped")
Return "$($ServiceName) has been shutdown."
function serviceOn
# Checks the all the service in the above $serviceNames.
foreach ($SeviceName in $ServiceNames)
# Check for service status if stopped this will start it and goes throug the loop again.
# until status matches running.
if ((Get-Service -Name $ServiceName).Status -eq "Stopped")
do
Start-Service $ServiceName
Start-Sleep -Seconds 20
until ((Get-Service $ServiceName).Status -eq "Running")
Return "$($ServiceName) has been turned on."
#søndag - Sunday,
#mandag - Monday,
#tirsdag - Tuesday
#onsdag - Wednesday,
#torsdag - Thursday,
#fredag - Friday,
#lørdag - Saturday
Switch ($OnOffSwitch)
'mandag_02:00' serviceOn
'mandag_17:00' serivcesOff
'tirsdag_02:00' serviceOn
'tirsdag_17:00' serviceOff
'onsdag_02:00' serviceOn
'onsdag_17:00' serviceOff
'torsdag_02:00' serviceOn
'lørdag_01:00' serviceOff
default Write-Output "Nothing matched"
这是最好的方法还是我应该使用if ... else if ... else
语句?有没有更好的办法?
【问题讨论】:
我只需要编写两个基本脚本来关闭和打开您的服务并使用任务调度程序执行它们。您真的不必重新制定日程安排。 serviceOff 应该是stop-service
对吧?
是的,应该是stop-service
我的错。
【参考方案1】:
基本上是stackprotector 所说的。使用本机任务调度程序将是最简单的方法。无论如何,这里有一些改进代码的技巧。我通常会将它们放入 cmets,但它不适合:
在函数servicesOff
中,您检查状态是否正在运行以及是否是您Start-Service
。我想你想在这里使用Stop-Service
。
在启动或停止服务后sleep
不是绝对必要的。这些 cmdlet 不称为异步,因此在服务完全启动之前睡眠甚至不会启动。但是,如果它们没有启动但导致错误,它们可能最终处于 Running
或 Stopped
之外的另一种状态,这会使您的脚本陷入无限循环,试图启动损坏的服务。
我会尽量避免像剧本中的工作日这样的文化习俗。有时脚本是在服务器的原始文化设置(英语)中执行的,而不是在您登录时可用的文化(在“德语”服务器上很难学到)。在脚本开头定义文化:
[System.Threading.Thread]::CurrentThread.CurrentCulture = "da-DK"
或者让它成为文化中立的:
(get-date).DayOfWeek
将始终返回英语工作日 ([DayOfWeek].GetEnumNames()
)。尽可能使用 [DateTime]
对象 (Get-Date
) 而不是它所代表的字符串。
由于[DateTime]
精确到 CPU 的刻度,因此您无法直接将其与-eq
或在开关中进行比较。使用-lt
/ -gt
或$Date.Hour
在你的脚本中我会这样做:
# PowerShell script to stop and start services.
# Variable assignement
$Date = Get-Date
$ServiceNames = @('CAPS8','CAPS9'); # Array to store service names.
function serivcesOff
# Checks the all the service in the above $serviceNames.
foreach ($SeviceName in $ServiceNames)
# Check for service status if stopped this will start it and goes throug the loop again.
# until status matches running.
if ((Get-Service -Name $ServiceName).Status -ne "Stopped") # changed this to not stopped instead of running
do
Stop-Service $ServiceName
#Start-Sleep -Seconds 20
until ((Get-Service $ServiceName).Status -ne "Running") # changed this to not running instead of stopped
Return "$($ServiceName) has been shutdown."
function serviceOn
# Checks the all the service in the above $serviceNames.
foreach ($SeviceName in $ServiceNames)
# Check for service status if stopped this will start it and goes throug the loop again.
# until status matches running.
if ((Get-Service -Name $ServiceName).Status -eq "Stopped")
do
Start-Service $ServiceName
#Start-Sleep -Seconds 20
until ((Get-Service $ServiceName).Status -eq "Running")
Return "$($ServiceName) has been turned on."
if ($Date.Hour -eq 2)
serviceOn
elseif ($Date.DayOfWeek -ne "Friday") # or -notin "Friday","Sunday"
if ($Date.Hour -eq 17)
serviceOff
if ($Date.DayOfWeek -eq "Saturday" -and $Date.Hour -eq 1 )
serviceOff
【讨论】:
我不知道$Date
对象也可以在没有 else 部分的情况下运行 if else 吗?
我自己在脚本$Date = Get-Date
的开头创建了$Date
。 (Get-Date).Hour
会更准确。当然你可以省略else
。没有人强迫你拥有else
。
哦...好吧,我认为 if 语句需要在 else if 中有一个 else 部分。
help about_if
以上是关于有没有更好的方法来使用 PowerShell 实现服务的开/关的主要内容,如果未能解决你的问题,请参考以下文章
有没有更好的方法来使用存储库在 Laravel 中分配 Eloquent 关系?
有没有更好更快的方法来使用推力从 CPU 内存复制到 GPU?
有没有更好(更干净)的方法来使用三元运算符(不重复代码)编写这个 JS 代码?