bugfix> powershell > 投稿

txtファイルにリストされているすべてのサービスをループするスクリプトを作成しようとしています。サービスのスタートアップの種類が正しいかどうかを確認し(変更しない場合)、必要に応じてサービスを開始します。私はPowershellがあまり得意ではなく、Googleから何も役に立たないでしょう。

私のテキストファイル:

Service A
Service B
Service C
Service D
Service E

現在のスクリプトは現在このようになっており、現時点ではテキストファイルからすべてのサービスを印刷できましたが、次の手順の情報が不足しています。

$services = Get-Content .\services.txt
## Pass each service object to the pipeline and process them with the Foreach-Object cmdlet
foreach ($service in $services) {
    
    Get-Service $service | Select-Object -Property Name, StartType, Status, DisplayName
    }

難しいのは、すべてのサービスが同じスタートアップの種類とステータスを持たないため、より複雑になることです。

  • サービスAは手動で実行する必要があります
  • サービスBは自動で実行されている必要があります
  • サービスCは手動で停止する必要があります

したがって、サービスAが手動で実行されていない場合、スクリプトはそれらを変更し、変更に関する情報を提供します(write-host?)。

コマンドのset-serviceでサービスのスタートアップの種類とステータスを変更し、get-serviceでステータスを一覧表示できるのはわかっていますが、スクリプトでそれを設定するにはまだスキルが足りません。これがこの方法で可能かどうか、またはこれを行うためのより良い方法であるかどうかはわかりません。

回答 3 件
  • サービスのテキストファイルをCsvファイルに変更すると、サービスの名前だけでなく、次のような目的のStartTypeおよびStatusもリストできるようになります。

    サービス、開始タイプ、ステータス
    サービスA、手動、実行中
    サービスB、自動、実行中
    サービスC、手動、停止
    

    次に、それを次のようにコーディングできます

    Import-Csv -Path .\services.csv | ForEach-Object {
        $changed = $false
        $service = Get-Service -Name $_.Service
        if ($service.StartType -ne $_.StartType) {
            Write-Host "Changing StartType for service $($service.Name)" -ForegroundColor Yellow
            $service | Set-Service -StartupType $_.StartType
            $changed = $true
        }
        if ($service.Status -ne $_.Status) {
            Write-Host "Changing Status for service $($service.Name)" -ForegroundColor Yellow
            $service | Set-Service -Status $_.Status
            $changed = $true
        }
        # refresh the info if you changed anything above
        if ($changed) { $service = Get-Service -Name $_.Service }
        # write out current status
        Write-Host "Service: $($service.Name) - StartType: $($service.StartType) - Status: $($service.Status)"
    }
    
    

  • 使用する必要はありません Select-ObjectGet-Service サービス名のパイプライン入力を直接受け入れます

    $Services = Get-Content .\services.txt | Get-Service
    ForEach( $Service in $Services )
    {
        If( $Service.StartType -eq 'Manual' -and $Service.Status -eq 'Running' )
        {        
            Set-Service -InputObject $service -StartupType 'Automatic'
        }
        # Add more logic as needed here!
    }
    
    

    ただし、サービスについてどのように決定するかは、質問からは明らかではありません。もちろん、一部のサービスは手動、自動などでなければなりません...テキストファイルに基づいて目的の状態を指示することを検討していますか?

    その場合、簡単な解決策は、設定をCSVファイルに保存することです。のようなフォーマット <ServiceName>, <DesiredStartType> 。次に、コードを再構成して必要な変更を適用し、コンソールへのフィードバックを改善できます。

    コメントに基づいて更新

    あなたはcsvファイルをOKにしたので、さらに@Theoの役立つ答えに基づいて構築します。次に、CSV入力ファイルを使用する別の方法を示します。この場合、サービスを抽出した後、入力をハッシュテーブルに変換しました。これにより、目的の構成を簡単に参照できます。

    Theoの答えから同じCSVレイアウトを想定:

    Service,StartType,Status
    Service A,Manual,Running
    Service B,Automatic,Running
    Service C,Manual,Stopped
    
    

    $DesiredConfig = Import-Csv c:\Temp\Services.csv
    $Services      = $DesiredConfig.Service | Get-Service
    # Flip config data to a dictionary
    $DesiredConfig = $DesiredConfig | Group-Object -Property Service -AsHashTable -AsString
    ForEach( $Service in $Services )
    {   
        $DesiredStart  = $DesiredConfig[$Service.Name].StartType
        $DesiredStatus = $DesiredConfig[$Service.Name].Status
        If( $Service.StartType -ne $DesiredStart -or $Service.Status -ne $DesiredStatus )
        {
            Write-Host "Changing $($Service.Name) StartType/Status : $($Service.StartType) / $($Service.Status) > $DesiredStart / $DesiredStatus) ..."
            $Service = $Service | Set-Service -StartupType $($DesiredConfig[$Service.Name].StartType) -Status $DesiredStatus -PassThru
            # You don't need to reassign or use -PassThru, however if you are going to post-report this spares you the need to
            # re-get-services.  You are going to run the set command anyhow!
        }
    }
    # Not needed, but just to check...
    $Services | Format-Table Name,Displayname,STartType,Status -AutoSize
    
    

    私はこれをテストしませんでしたが、アプローチはしっかりしているはずです。

    参考になれば幸いです。ありがとう。

  • これでうまくいきました。 @theoと@Stevenに感謝

あなたの答え