0

アップデート

Rename-Itemプロセスで名前を変更して変更するだけで、これを解決できましMove-Itemた(これは、物事が実際に機能するためのばかげた方法です)。ただし、これはreturnステートメントが実行されなかった理由、または少なくとも実行された場合、関数が を呼び出し続けた理由の謎を解決しませんNew-Item


ログオン時にアイテムの名前を変更しようとしていますが、アイテムが存在しない場合は作成したいと考えています。これを行う関数は次のとおりです。

function SelfHelpAppData {
    $ErrorActionPreference = "Stop"
    trap {Log-Error $_ $MyInvocation.MyCommand; Continue}

    $files = Get-ChildItem $AppData

    ForEach ($file in $files) {
        If ($file.Name -match 'qxjz') {

            Rename-Item $file.PSPath "qxjz$env:COMPUTERNAME.txt" -Force
            WriteLogonEntryData
            return
        }
    }

    New-Item "$AppData\qxjz$env:COMPUTERNAME.txt"
    WriteLogonEntryData
}

ただし、これを実行すると、ログに次のエラーが表示されます。

Windows PowerShell は非対話型モードです。読み取りおよびプロンプト機能は使用できません。

\DC1\NETLOGON\PSSubs\mainlogon.ps1:841 char:5 + New-Item "$AppData\qxjz$env:COMPUTERNAME.txt" + ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

その後:

ファイルが既に存在する場合、ファイルを作成できません。

\DC1\NETLOGON\PSSubs\mainlogon.ps1:835 char:13 + Rename-Item $file.PSPath "qxjz$env:COMPUTERNAME.txt" -Force + ~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

しかし、最初の行 (rename-item) を実行しようとした場合、他の行がチャンスを得る前に関数が返されているはずなので、これは不可能です。returnステートメントをに変更しようとしましreturn $nullたが、効果はありません。ここで何が起こっているか知っている人はいますか?

ありがとうございました


ログエラーコードは次のとおりです。

function Log-Error {
    param (
        $error,
        [string]$sub
    )
    $ErrorActionPreference = "Stop"
    trap {Log-Error $_ $MyInvocation.MyCommand; Continue}

    $filename = "\\file\administration\Unused\LogonScriptErrors\$env:USERNAME - $env:COMPUTERNAME - $(Get-Date -Format ddMMyyyy-HHmmss) - $($error.InvocationInfo.ScriptLineNumber).log"

    New-Item $filename -ItemType File -Value "$($error.Exception.Message) `r`n `r`n $($error.InvocationInfo.PositionMessage) `r`n `r`n $sub"
}
4

2 に答える 2

2

あなたが観察した動作の理由は、continueステートメントtrapリストにあります。これにより、スクリプトはエラーが発生したループの後の次の命令に進みます。これは文書化された動作です。

エラーが発生した場合にスクリプトで操作を終了させたい場合は、continue. 必要に応じて関数を終了し、 に変更continuereturnます。

そうは言っても、視覚的にもより優れた制御を提供する/から離れて代わりにtrap使用することをお勧めします。trycatch

ところで、New-Item必須パラメーターを省略したため、エラーが発生します-Type。そのパラメーターがないと、コマンドレットは必要な情報の入力を求めようとしますが、スクリプトが非対話的に実行されるため、入力できません。エラーを取り除くには-Type File、ステートメントに追加します。

于 2016-04-04T15:27:42.650 に答える
1

PowerShell でのエラー アクション処理は、従来の例外処理よりもはるかに「緩い」ため、PS エラー トラップが毎回スローされます。私が行ったいくつかの改訂:

  • グローバルブランケットトラップを行う代わりに、try/catch を使用してください。
  • -Forcenew-item ステートメントと rename-item ステートメントの両方で使用します。
  • $env:あなたはインを忘れました$env:AppData
  • コンソールの言葉遣いを回避するには、| Out-Null

ほとんどの場合、個々の try/catch エラー処理を行うのは面倒で醜いため、trap{}. 単純な名前変更/ファイル作成操作でそのレベルのエラー処理が本当に必要な場合は、代わりに一致ケースで一般的な例外処理を行うことができます。

function Do-Stuff {

    $EAPREF = 'Stop'
    $FILES = gci $env:APPDATA

    try {
        ForEach ($file in $FILES) {
            If ($file.Name -match 'qxjz') {
            Rename-Item $file.PSPath "qxjz$env:COMPUTERNAME.txt" -Force -ErrorAction $EAPREF | Out-Null
            return
            }
        }
        New-Item "$env:AppData\qxjz$env:COMPUTERNAME.txt" -ItemType 'File'  -Force -ErrorAction $EAPREF | Out-Null
    } 
    catch [System.Exception]{
        #Error handling here using type/parameter qualifier cases.

        if ($_.FullName -eq 'So and So'){
            # Handle the error a certain way for so-and-so
        }

        if ($_.FullName -eq 'Other exception type you expect'){
            # Handle another type of error separately
        }
    }
}
于 2016-04-04T15:50:13.043 に答える