退货声明无效

时间:2016-04-04 14:22:01

标签: powershell logonserver

更新

我能够通过将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处于NonInteractive模式。读取和提示功能不可用。

     

在\ 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” - 强制   + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~

但这是不可能的,就好像第一行(rename-item)试图运行一样,那么该函数应该在另一行有机会之前返回。我尝试将return语句更改为return $null,但没有效果。有谁知道这里发生了什么?

谢谢

以下是Log-Error代码:

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"
}

2 个答案:

答案 0 :(得分:2)

您观察到的行为的原因是continue语句列表中的trap。它会导致脚本在发生错误的循环之后继续执行下一条指令。这是documented行为。

如果您希望脚本在发生错误时终止操作,请删除continue。如果您需要,只需退出功能更改continuereturn

话虽如此,我建议远离trap并使用try / catch代替,这样即使在视觉上也能提供更好的控制。

BTW,发生New-Item错误,因为您省略了必需参数-Type。如果没有该参数,cmdlet会尝试提示您输入所需信息,但不能,因为脚本是以非交互方式运行的。要消除错误,请在语句中添加-Type File

答案 1 :(得分:1)

每次都会抛出PS错误陷阱,因为PowerShell中的错误操作处理比传统的异常处理更加“松散”。我做了一些修改:

  • 使用try / catch。
  • 而不是进行全局覆盖陷阱
  • 对new-item和rename-item语句使用-Force
  • 您忘记了$env:
  • 中的$env:AppData
  • 您可以使用| Out-Null
  • 绕过控制台verbage

在大多数情况下,执行单独的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
        }
    }
}