1

すべてのSQL ServerインスタンスでSQL Agentサービスをリモートで再起動しようとしています。 CSVファイルにリストされている各サーバーのローカル管理者権限を持つアカウントにログインしているときに、開発サーバーのいずれかから次のスクリプトを実行します。このファイルには、この開発サーバーとリモートの両方にあるすべてのSQLインスタンスのHostNameとInstanceNameが含まれています。すべてがSQL Server 2008 R2または2012のいずれかを実行しているWindows Server 2008 R2または2012です。PowerShellは管理者として実行されています。リモートコンピュータのRestart-ServiceがNoServiceFoundForGivenNameになりますが、Get-Serviceが機能します

$Servers = Import-CSV C:\Temp\InstanceList.csv 
ForEach ($Line In $Servers) 
{ 
    $sqlHostName = $Line.hostName 
    $sqlInstanceName = if ($Line.instanceName -eq "") {$Line.instanceName} else {("$" + $Line.instanceName)} 
    $serviceName = if ($sqlInstanceName -eq "") {"SQLSERVERAGENT"} else {"SQLAgent" + $sqlInstanceName} 
    Get-Service -computer $sqlHostName ($serviceName) 
    Get-Service -computer $sqlHostName ($serviceName) | Restart-Service 
} 

ローカルマシンのインスタンスでは成功しますが、リモートインスタンスでは失敗します。ここでは、リモートのデフォルトインスタンスで表示されるエラーです。最初の行は、私は、正しいサービス名を持っていることを示しており、次の行は、それが存在しないと主張:

Running SQLSERVERAGENT  SQL Server Agent (MSSQLSERVER) 
Restart-Service : Cannot find any service with service name 'SQLSERVERAGENT'. 
At line:11 char:70 
+ Get-Service -computer $sqlHostName ($serviceName) | Restart-Service <<<< 
    + CategoryInfo   : ObjectNotFound: (SQLSERVERAGENT:String) [Restart-Service], ServiceCommandException 
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.RestartServiceCommand 

は有効-Remotingを前に、各サーバー上でローカルに実行されていました。

Get-Serviceはサービス名を表示できますが、Restart-Serviceはサービスが存在しないと主張するのはなぜですか。アクセス許可の問題である必要があるように感じますが、解決方法はわかりません。何か案は?

答えて

2

これは、Get-Serviceがまだローカルで実行されているためです。パイプラインの前のコマンドの-Computerパラメータについては知らないし、Get-Serviceのような-Computerもサポートしていない。

オプション1:使用して入力します-PSSessionはあなたがEnter-を使って、問題のコンピュータ上でリモートPowerShellセッションを入力することができます

リモートサービスの再起動、サービスを使用するには、オプションのカップルを持っていますPSSession。そうすることで、基本的にはリモートコンピュータ上にシェルが開き、与えられたコマンドが実行されます。 Enter-PSSessionは-Credentialパラメーターもサポートしているため、ローカルで実行しているアカウントがリモートコンピューターのアクセス許可を持つ管理者アカウントでない場合は、まず資格情報オブジェクトを作成して使用します。あなたのプロンプトが変わる、ということを実行すると

$Credential = Get-Credential 
Enter-PSSession -ComputerName $ComputerName -Credential $Credential 

:コードは次のようになります。それは、広告角括弧内のリモートコンピュータの名前が(あなたが別のに対してコマンドを実行している知っているようにしますホスト)。

[ComputerName]: PS C:\Users\Username\Documents> 

、あなたが実行するすべてのコマンドは、ターゲットコンピュータで実行されます:おそらく、またそうのように、リモートホスト上のドキュメントフォルダ\ユーザーにデフォルト設定しようとしています。もはやGet-Serviceの-Computerは必要ありません。だから、あなただけ実行することができます。

Get-Service ($serviceName) | Restart-Service 

を完了したら、ちょうどあなたがあなたの地元のプロンプトに戻るには、exit-PSSessionコマンドを使用して、確認してください。

オプション2:使用して、Invoke-Commandコマンド

(あなたがやっている自動化に、より良い自分自身を貸すかもしれないし、1)別のオプションは、Invoke-Commandコマンドを使用することです。 Invoke-Commandは-Credentialと-ComputerNameの両方のパラメータと-ScriptBlockパラメータをサポートしています。 ScriptBlockは、独自のパラメータを持つコードを簡単に渡して変更できるため、きれいです。したがって、上記のあなたの例では、あなたはこのような何かを行うことができます:

$ScriptBlock = {Get-Service | Where-Object {$_.Name -like "SQL*"} | Restart-Service} 
Invoke-Command -ComputerName $ComputerName -ScriptBlock $ScriptBlock 

あなたが何をしようとして、私はそうのようなスクリプトを書き換えたい方法に基づいて:

$Servers = Import-CSV C:\Temp\InstanceList.csv 
$ScriptBlock = {param([string] $RemoteServiceName) Get-Service | Where-Object {$_.Name -eq $RemoteServiceName} | Restart-Service} 

ForEach ($Line In $Servers) 
{ 
    $sqlHostName = $Line.hostName 
    $sqlInstanceName = if ($Line.instanceName -eq "") {$Line.instanceName} else {("$" + $Line.instanceName)} 
    $serviceName = if ($sqlInstanceName -eq "") {"SQLSERVERAGENT"} else {"SQLAgent" + $sqlInstanceName} 
    Invoke-Command -ComputerName $sqlHostName -ScriptBlock $ScriptBlock -ArgumentList $serviceName 
} 

Iよあなたのループのロジックを使用して、私は、私は、Invoke-Commandコマンドを実行したい-ComputerNameを指定するために、あなたの.CSVファイルから取得した変数を使用しています、と私は最終的に取得する値を提供するためには、ArgumentListとパラメータとのScriptBlockを使用しています走る

あなたは概念のカップルについての詳細を知りたい場合は、ここでいくつかのリンクです:

  1. のScriptBlock情報:https://technet.microsoft.com/en-us/library/hh847893.aspx
  2. Invoke-Commandコマンド:https://technet.microsoft.com/en-us/library/hh849719.aspx

オプション3:使用もちろん

オブジェクトのメソッド、それは難しいことである必要はありません。 Get-Serviceを使用して変数へのサービスを取得し、そのオブジェクトに対して.Restart()メソッドを使用できます。あなたは、サービスを再起動するようにオブジェクトを渡すことはできませんが、あなたはだけでメソッドを呼び出すことができますし、それもリモートで、そのサービスを再起動します:

$Servers = Import-CSV C:\Temp\InstanceList.csv 
ForEach ($Line In $Servers) 
{ 
    $sqlHostName = $Line.hostName 
    $sqlInstanceName = if ($Line.instanceName -eq "") {$Line.instanceName} else {("$" + $Line.instanceName)} 
    $serviceName = if ($sqlInstanceName -eq "") {"SQLSERVERAGENT"} else {"SQLAgent" + $sqlInstanceName} 
    $Service = Get-Service -computer $sqlHostName ($serviceName) 
    $Service.Restart() 
} 

そして、それは、PowerShellのは素晴らしいことだ一つのことです。それらの答えのどれもあなたがそれらのどれかを使うことができるという点で「間違っている」ものではありません。彼らはすべての潜在的な解決策であり、私はそこにさらに多くがあると確信しています。

+1

ありがとうございました!それがトリックでした。 –

関連する問題