更新
我能够通过将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"
}
答案 0 :(得分:2)
您观察到的行为的原因是continue
语句列表中的trap
。它会导致脚本在发生错误的循环之后继续执行下一条指令。这是documented行为。
如果您希望脚本在发生错误时终止操作,请删除continue
。如果您需要,只需退出功能更改continue
至return
。
话虽如此,我建议远离trap
并使用try
/ catch
代替,这样即使在视觉上也能提供更好的控制。
BTW,发生New-Item
错误,因为您省略了必需参数-Type
。如果没有该参数,cmdlet会尝试提示您输入所需信息,但不能,因为脚本是以非交互方式运行的。要消除错误,请在语句中添加-Type File
。
答案 1 :(得分:1)
每次都会抛出PS错误陷阱,因为PowerShell中的错误操作处理比传统的异常处理更加“松散”。我做了一些修改:
-Force
。$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
}
}
}