至少我认为PowerShell没有正确处理参数?

Posted

技术标签:

【中文标题】至少我认为PowerShell没有正确处理参数?【英文标题】:PowerShell not processing arguments correctly at least I think so? 【发布时间】:2021-08-16 23:57:57 【问题描述】:

我编写了这段代码来格式化闪存驱动器:

[CmdLetBinding()]

Param (
  [Parameter(Mandatory=$True)]
    [String] $DrvLtr,
  [Parameter(Mandatory=$False)]
    [ ValidateSet("NTFS","ReFS","exFAT",
                  "FAT32","FAT")]
    [String] $FileSys = "NTFS" ,
  [Parameter(Mandatory=$False)]
    [Switch] $TestIt
)

$FVArgs = @DriveLetter = $DrvLtr
            FileSystem  = $FileSys
            Force       = $True
            Full        = $True
            Confirm     = $True
            WhatIf      = $($TestIt.isPresent)
           

 Format-Volume @FVArgs

当我调用代码如下:

PS> .\Dev-New-Format-FlashDrive.ps1 -TestIt -DrvLtr x

它的运行就像 Format-Volume 的 -TestIt(-WhatIf 的值)和 -Confirm 参数不存在一样。处理 Format-Volume 并格式化驱动器。

我在 Volume-Format 行使用断点运行代码并测试了参数,结果如下:

PS> .\Dev-New-Format-FlashDrive.ps1 -TestIt -DrvLtr x

Hit Line breakpoint on 'G:\BEKDocs\Scripts\Dev-New-Format-FlashDrive.ps1:24'
PS> $FVArgs

Name                           Value                                           
----                           -----                                           
FileSystem                     NTFS                                            
Force                          True                                            
Confirm                        True                                            
WhatIf                         True                                            
DriveLetter                    x                                               
Full                           True                                            

PS> 

想法?

编辑: Theo,回复您的帖子:

Test Results:

PS> .\Test\Test-Format-FlashDriveOrdered.ps1 -DrvLtr "X" -FileSys FAT32 -TestIt

DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatu
                                                               s               
----------- ------------ -------------- --------- ------------ ----------------
X                        FAT32          Removable Healthy      OK              

PS> .\Test\Test-Format-FlashDriveMovedSwitches.ps1 -DrvLtr "X" -FileSys FAT32 -TestIt

DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatu
                                                               s               
----------- ------------ -------------- --------- ------------ ----------------
X                        FAT32          Removable Healthy      OK              

# Force set to False on all the following...

# WhatIf Removed
PS> .\Test\Test-Format-FlashDrive.ps1 -DrvLtr "X" -FileSys FAT32 -TestIt1
DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatu
                                                               s               
----------- ------------ -------------- --------- ------------ ----------------
X                        FAT32          Removable Healthy      OK              


# Whatif Replaced Confirm Removed
PS> .\Test\Test-Format-FlashDrive.ps1 -DrvLtr "X" -FileSys FAT32 -TestIt

DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatu
                                                               s               
----------- ------------ -------------- --------- ------------ ----------------
X                        FAT32          Removable Healthy      OK              

【问题讨论】:

我不认为这是一个参数处理的事情;看起来您不是唯一一个发现 Format-Volume -WhatIf 不起作用的人; link1 和 link2 和 link3 谢谢。现在为什么 -Confirm 开关不起作用? 也许我们的 powershell pops (mklement) 可以在这个问题上提供一些启示/见解。很高兴我在自己尝试之前看到了这个! 【参考方案1】:

这不是一个答案,我只是想了解更多,所以请您告诉我们在以下情况下会发生什么:

关于Confirm switch

默认情况下,Shell 会自动将 Confirm 开关应用于具有以下动词的 cmdlet:

清除、禁用、卸载、移动、删除、停止、暂停、卸载

Format 似乎不在其中.. 该页面还指出“如果您想手动将确认开关应用于命令,请在命令末尾包含确认开关

WhatIf 开关几乎相同: “当您与 WhatIf 开关一起运行命令时,您将 WhatIf 开关放在命令的末尾

对我来说,这可能意味着您不能在飞溅的 Hashtable (??) 中使用这些开关

出于好奇,如果你尝试会发生什么

[CmdLetBinding()]

Param (
  [Parameter(Mandatory=$True)]
    [String] $DrvLtr,
  [Parameter(Mandatory=$False)]
    [ ValidateSet("NTFS","ReFS","exFAT","FAT32","FAT")]
    [String] $FileSys = "NTFS" ,
  [Parameter(Mandatory=$False)]
    [Switch] $TestIt
)

# try with an [ordered] hash, so the Confirm and WhatIf switches are last
$FVArgs = [ordered]@
    DriveLetter = $DrvLtr
    FileSystem  = $FileSys
    Force       = $True
    Full        = $True
    Confirm     = $True
    WhatIf      = $($TestIt.isPresent)


Format-Volume @FVArgs

如果你把它们从 splatting hashtable 中取出会发生什么:

[CmdLetBinding()]

Param (
  [Parameter(Mandatory=$True)]
    [String] $DrvLtr,
  [Parameter(Mandatory=$False)]
    [ ValidateSet("NTFS","ReFS","exFAT","FAT32","FAT")]
    [String] $FileSys = "NTFS" ,
  [Parameter(Mandatory=$False)]
    [Switch] $TestIt
)

$FVArgs = @
    DriveLetter = $DrvLtr
    FileSystem  = $FileSys
    Force       = $True
    Full        = $True


Format-Volume @FVArgs -Confirm -WhatIf:($TestIt.isPresent)

【讨论】:

Theo,查看我的测试结果的编辑问题。似乎没有任何效果! @RetiredGeek 哇...感谢您测试所有这些。 Sems 一个真正的错误 cmdlet..

以上是关于至少我认为PowerShell没有正确处理参数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 PowerShell 不处理这个 $?正确退出代码?

“(在此时出现意外”是从Powershell运行批处理文件时)

在 PowerShell 中创建批处理作业

Powershell 和 schtask 与具有空间的任务

Powershell 无法返回正确的退出代码

尝试创建计划任务时出现Powershell错误?无法处理参数“参数”的参数转换