有没有更好的方法来使用 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 不称为异步,因此在服务完全启动之前睡眠甚至不会启动。但是,如果它们没有启动但导致错误,它们可能最终处于 RunningStopped 之外的另一种状态,这会使您的脚本陷入无限循环,试图启动损坏的服务。 我会尽量避免像剧本中的工作日这样的文化习俗。有时脚本是在服务器的原始文化设置(英语)中执行的,而不是在您登录时可用的文化(在“德语”服务器上很难学到)。在脚本开头定义文化:

[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 实现服务的开/关的主要内容,如果未能解决你的问题,请参考以下文章

有没有更好的方法来使用 Youtube PHP API

有没有更好的方法来使用存储库在 Laravel 中分配 Eloquent 关系?

有没有更好更快的方法来使用推力从 CPU 内存复制到 GPU?

有没有更好(更干净)的方法来使用三元运算符(不重复代码)编写这个 JS 代码?

有没有更好的方法来使用没有 eval 的字符串来获取对动作脚本中影片剪辑的引用

需要一种更好的方法来使用 jquery 验证插件来验证 ASP.NET 复选框?