Powershell if-else不遵循任何一个分支

Beo*_*e42 3 powershell boolean-logic if-statement

我有PowerShell代码

$target_dir = "\\server\share\"
$DelTmpStatus = "init value"
if ( Test-Path ( $target_dir + "receivals.tmp") )
{
    del ( $target_dir + "receivals.tmp")
    $DelTmpStatus = "Present and delete status $?"
} else {
    $DelTmpStatus = "NA"
}
Run Code Online (Sandbox Code Playgroud)

有时它会通过$ DelTmpStatus设置为“初始值”而通过本节。

if-else结构如何不遵循任何一条路径?当给if函数一个错误而不是true或false时,powershell中的if-else结构不执行任何操作吗?

$ PSVersionTable.psversion为3.0

编辑:我自己运行时,无论是完全运行还是分步运行,我都没有任何错误或问题。但是有时计划的作业将运行,而$ DelTmpStatus仍将是“初始值”,我想当\\server\share\路径由于服务器处于低功耗模式而在一夜之间花费的时间太长而无法响应并且测试路径功能超时时,就会发生这种情况。虽然我不确定这是否是原因。

编辑:做测试的结果

  • 使用不存在的服务器$target_dir使其遵循else路径并设置$DelTmpStatus为“ NA”
  • $target_dir = "C:\..\..\invalid\"在测试路径中使用无效的路径(例如结果),将错误写入stderr并返回true(不理想,但无论如何),使程序顺着尝试删除文件的操作(再次出现错误),然后将其设置$DelTmpStatus为“存在并删除状态为False”。这并不是特别有帮助的事情,但是至少执行了if-else语句中的代码。

Beo*_*e42 5

看来,如果条件区域内的命令执行失败且未返回值,则整个if-else块都不会执行,并且继续出错会选择继续在if-else块下面。

如何模拟问题

尽管这不是我的真实代码中发生的事情,但确实会产生相同的问题,即if-else块未执行。它甚至每次都这样做。

if ( Test-Path -invalid-switch )
{
    write-output "true path of if statement"
} else {
    write-output "false path of if statement"
}
write-output "finished if statement"
Run Code Online (Sandbox Code Playgroud)

有输出

Test-Path : A parameter cannot be found that matches parameter name 'invalid-switch'.
At C:\scripts\test.ps1:1 char:16
+ if ( Test-Path -invalid-switch )
+                ~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.TestPathCommand

finished if statement
Run Code Online (Sandbox Code Playgroud)

修复

要解决此问题,可能需要事先测试的if()条件要删除可能有错误的代码,并在if语句中添加逻辑以处理潜在的故障。为了修正实际的代码以免出现此问题,我现在将代码更改为

$err = $false
try { $tmpStatus = Test-Path ( $target_dir + "receivals.tmp") }
catch
{
    $tmpStatus = $error | foreach { $_.Exception }
    $err = $true
}
if ( $err -or $tmpStatus ) 
{
    del ( $target_dir + "receivals.tmp")
    $DelTmpStatus = $?
} else {
    $DelTmpStatus = "NA"
}
Run Code Online (Sandbox Code Playgroud)

精明的人会意识到,我可以只用线条代替所有这些

$tmpStatus = test-path ( $target_dir + "receivals.tmp")
del ( $target_dir + "receivals.tmp")
$DelTmpStatus = $?
Run Code Online (Sandbox Code Playgroud)

因为我尝试删除文件,即使它在查找文件时出错。唯一的区别是,较短的代码将经常出现错误,但仍执行相同的功能。

但是,使用更长的代码并进行更多错误检查可以更加清楚地了解这种情况,因为$ tmpStatus带有该值

System.Management.Automation.CommandNotFoundException: The term 'Test-Path' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这仍然让我想知道发生了什么...?“ Test-Path”如何在几天之内成为有效的cmdlet,而在另一些日子却无法成为有效的cmdlet,而同一计划中的同一台计算机上运行的脚本却完全相同。作为额外的奖励,在“ Test-Path”不是有效的cmdlet的日子里,当我稍后在同一脚本中再次使用它时,每次都可以正常工作。