有没有更好的方法来使用 PowerShell 实现服务的 on/off

Is there a better way to achieve the on/off of the services using PowerShell

我已经创建了一个脚本来停止 运行 我们在其中一台服务器上 运行 的一些自定义服务。我想在下午 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 语句?有没有更好的方法?

基本上是 stackprotector 所说的。使用本机任务调度程序将是最简单的方法。不管怎样,这里有一些改进代码的技巧。我通常会把它们放在评论中,但它不适合:
在函数 servicesOff 中,您检查状态是否为 运行,如果是您 Start-Service。我想你想在这里使用 Stop-Service
在启动或停止服务后 sleep 并不是绝对必要的。这些 cmdlet 不称为异步,因此在服务完全启动之前甚至不会开始休眠。但是,如果它们不启动但导致错误,它们可能会以 RunningStopped 以外的其他状态结束,这将使您的脚本陷入无限循环,试图启动损坏的服务。
我会尽量避免像脚本中的工作日这样的文化习俗。有时,脚本会在服务器的原始文化设置(英语)中执行,而不是您登录时可用的文化(在“德语”服务器上以艰难的方式学习)。要么在脚本开头定义文化:

[System.Threading.Thread]::CurrentThread.CurrentCulture = "da-DK" 

或使其文化中立: (get-date).DayOfWeek 总是 return 英语工作日 ([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
    }
}