8

私はたくさんのスクリプトを持っています。変更を加えた後、私はそれらすべてを実行して、何かが壊れたかどうかを確認するのが好きです。それぞれをループして、新しいデータで実行するスクリプトを作成しました。

私のループの中で私は現在実行していpowershell.exe -command <path to script>ます。それがこれを行うための最良の方法なのか、それとも2つのインスタンスが完全に分離しているのかはわかりません。

PowerShellのクリーンなインスタンスでスクリプトを実行するための推奨される方法は何ですか?それとも「セッション」と言うべきですか?

4

4 に答える 4

8

使用powershell.exeすることは良いアプローチのようですが、もちろんその長所と短所があります。

長所:

  • 各スクリプトは、個別のクリーンセッションで呼び出されます。
  • クラッシュしても、テストプロセス全体が停止するわけではありません。

短所:

  • 呼び出しpowershell.exeはやや遅いです。
  • テストは終了コードに依存しますが、0は必ずしも成功を意味するわけではありません。

潜在的な問題としての問題として言及されている短所はありません。

デモスクリプトは以下のとおりです。PSv2およびv3でテストされています。スクリプト名には、スペース、アポストロフィ、角かっこ、バッククォート、ドルなどの特殊文字が含まれる場合があります。コメント要件で言及されているものの1つは、コード内のスクリプトパスを取得する機能です。提案されたアプローチでは、スクリプトは次のように独自のパスを取得できます $MyInvocation.MyCommand.Path

# make a script list, use the full paths or explicit relative paths
$scripts = @(
    '.\test1.ps1' # good name
    '.\test 2.ps1' # with a space
    ".\test '3'.ps1" # with apostrophes
    ".\test [4].ps1" # with brackets
    '.\test `5`.ps1' # with backticks
    '.\test $6.ps1' # with a dollar
    '.\test ''3'' [4] `5` $6.ps1' # all specials
)

# process each script in the list
foreach($script in $scripts) {
    # make a command; mind &, ' around the path, and escaping '
    $command = "& '" + $script.Replace("'", "''") + "'"

    # invoke the command, i.e. the script in a separate process
    powershell.exe -command $command

    # check for the exit code (assuming 0 is for success)
    if ($LastExitCode) {
        # in this demo just write a warning
        Write-Warning "Script $script failed."
    }
    else {
        Write-Host "Script $script succeeded."
    }
}
于 2012-11-11T07:41:09.920 に答える
6

PowerShell 2.0 以降を使用している場合は、ジョブを使用してこれを行うことができます。各ジョブは個別の PowerShell プロセスで実行されます。例:

$scripts = ".\script1.ps1", ".\script2.ps1"

$jobs = @()
foreach ($script in $scripts)
{
    $jobs += Start-Job -FilePath $script
}

Wait-Job $jobs

foreach ($job in $jobs)
{
    "*" * 60
    "Status of '$($job.Command)' is $($job.State)"
    "Script output:"
    Receive-Job $job
}

また、PowerShell Community Extensionsも確認してください。Test-Scriptスクリプト ファイルの構文エラーを検出できるコマンドがあります。もちろん、実行時エラーはキャッチされません。

于 2012-10-27T02:13:28.083 に答える
3

PowerShell V3 ユーザー向けのヒント: 私たち (PowerShell チーム) は、Runspace クラスに ResetRunspace() という新しい API を追加しました。この API は、グローバル変数テーブルをその実行空間の初期状態にリセットします (その他のいくつかのクリーンアップも行います)。それがしないのは、関数の定義、型、およびフォーマット ファイルを削除するか、モジュールをアンロードすることです。これにより、API が大幅に高速化されます。また、Runspace は、RunspaceConfiguration インスタンスではなく、InitialSessionState オブジェクトを使用して作成されている必要があることに注意してください。ResetRunspace() は、V3 のワークフロー機能の一部として追加され、スクリプトでの並列実行を効率的にサポートします。

于 2012-11-10T05:12:15.423 に答える
2

2 つのインスタンスは、2 つの異なるプロセスであるため、完全に分離されています。一般に、スクリプトを実行するたびに Powershell プロセスを開始するのは、最も効率的な方法ではありません。スクリプトの数と再実行の頻度によっては、全体的なパフォーマンスに影響を与える可能性があります。そうでない場合は、すべてそのままにしておきます。

別のオプションは、同じ実行空間で実行することです(これは正しい言葉です) が、毎回すべてをクリーンアップします。それを行う方法については、この回答を参照してください。または、以下の抽出を使用します。

$sysvars = get-variable | select -Expand name
function remove-uservars {
 get-variable |
   where {$sysvars -notcontains $_.name} |
     remove-variable
}
于 2012-10-27T00:46:40.837 に答える