環境:Windows Server 2022 21H2,Powershell 7.2(以管理員身份運行)
我有一個實作 ShouldProcess 的腳本,它在 Windows PowerShell 5 中運行良好。但是,在 PowerShell 7 中,該腳本總是在Cannot find an overload for "ShouldProcess" and the argument count: "1". MSDoc 處拋出錯誤 ShouldProcess表示$PSCmdlet.ShouldProcess()存在且應該作業的單引數多載。
它失敗了,如上所述。為什么?
有問題的腳本粘貼在下面;它在一個腳本模塊中:
function Remove-DomainUserProfile {
<#
#Comment-based help removed for space considerations
#>
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="High")]
param(
[Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName='SpecificProfile')]
[Parameter(ParameterSetName='ByAge')]
[Parameter(ParameterSetName='AllProfiles')]
[String[]]$ComputerName = $env:ComputerName,
[Parameter(Mandatory=$true,ParameterSetName='SpecificProfile')]
[Parameter(ParameterSetName='ByAge')]
[Alias("UserName","sAMAccountName")]
[String]$Identity,
[Parameter(ParameterSetName='ByAge')]
[Parameter(ParameterSetName='AllProfiles')]
[Switch]$DomainOnly,
[Parameter(ParameterSetName='SpecificProfile')]
[Parameter(ParameterSetName='ByAge')]
[Int]$Age,
[Parameter(Mandatory=$true,ParameterSetName='AllProfiles')]
[Switch]$All
)
BEGIN {
if (-NOT (Test-IsAdmin)) {
Write-Output "This function requires being run in an Administrator session! Please start a PowerShell
session with Run As Administrator and try running this command again."
return
}
$NoSystemAccounts = "SID!='S-1-5-18' AND SID!='S-1-5-19' AND SID!='S-1-5-20' AND NOT SID LIKE 'S-1-5-%-500' "
# Don't even bother with the system or administrator accounts.
if ($DomainOnly) {
$SIDQuery = "SID LIKE '$((Get-ADDomain).DomainSID)%' " # All domain account SIDs begin
with the domain SID
} elseif ($Identity.Length -ne 0) {
$SIDQuery = "SID LIKE '$(Get-UserSID -AccountName $Identity)' "
}
$CutoffDate = (Get-Date).AddDays(-$Age)
$Query = "SELECT * FROM Win32_UserProfile "
}
PROCESS{
ForEach ($Computer in $ComputerName) {
Write-Verbose "Processing Computer $Computer..."
if ($SIDQuery) {
$Query = "WHERE " $SIDQuery
} else {
$Query = "WHERE " $NoSystemAccounts
}
if ($All) {
Write-Verbose "Querying WMI using '$Query'"
$UserProfiles = Get-WMIObject -ComputerName $Computer -Query $Query
} else {
Write-Verbose "Querying WMI using '$Query' and filtering for profiles last used before $CutoffDate ..."
$UserProfiles = Get-WMIObject -ComputerName $Computer -Query $Query | Where-Object {
[Management.ManagementDateTimeConverter]::ToDateTime($_.LastUseTime) -lt $CutoffDate }
}
ForEach ($UserProfile in $UserProfiles) {
if ($PSCmdlet.ShouldProcess($UserProfile)) {
Write-Verbose "Deleting profile object $UserProfile ($(Get-SIDUser $UserProfile.SID))..."
$UserProfile.Delete()
}
}
}
}
END {}
}
uj5u.com熱心網友回復:
為了補充Santiago Squarzon 的出色分析:
該行為至少出現在 PowerShell 7.2.1 中,應被視為錯誤,因為任何物件都應在 .NET 方法呼叫中自動轉換為字串。
沒有理由讓
[pscustomobject]aka[psobject]實體的行為不同于任何其他型別的實體(無論隱式字串化在給定情況下是否有意義);舉一個簡單的例子:- 如果
(42).ToString((Get-Item /))有效,... - ...沒有理由不
(42).ToString(([pscustomobject] @{ foo=1 }))應該。 - 請注意,cmdlet/函式/腳本背景關系中的隱式字串化不受影響;例如,
Get-Date -Format ([pscustomobject] @{ foo=1 })不會導致錯誤。
- 如果
請參閱GitHub 問題 #16988。
完全涉及序列化基礎結構的原因是過時的WMI cmdlet(例如PowerShell (Core) v6
Get-WmiObject中不再原生提供) ,并且隱式使用它們會利用Windows PowerShell 兼容性功能:這需要使用隱藏的
powershell.exe子行程,與之通信需要使用序列化,在此期間大多數非原始型別會丟失其型別標識,并使用包含原始物件屬性副本的無方法實體進行模擬。[psobject]在 PowerShell v3 及更高版本中,尤其是在 PowerShell (Core) v6 中,請改用CIM cmdlet,例如
Get-CimInstance:- 雖然在許多方面類似于 WMI cmdlet,但一個重要的區別是從 CIM cmdlet 回傳的物件沒有方法;相反,必須通過呼叫方法
Invoke-CimMethod。
- 雖然在許多方面類似于 WMI cmdlet,但一個重要的區別是從 CIM cmdlet 回傳的物件沒有方法;相反,必須通過呼叫方法
有關更多資訊,請參閱此答案。
uj5u.com熱心網友回復:
作為參考,此錯誤可以在 PowerShell 版本 5.1 和 Core 上重現。重現的步驟是將System.Management.Automation.PSObject作為引數傳遞給.ShouldProcess(String)多載。通過查看您提到序列化物件的評論,這是有道理的。在下面的示例中,如果System.Diagnostics.Process物件未序列化,則它在兩個版本上都可以正常作業。
function Test-ShouldProcess {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]
param()
$obj = [System.Management.Automation.PSSerializer]::Deserialize(
[System.Management.Automation.PSSerializer]::Serialize((Get-Process)[0])
)
# will throw
if ($PSCmdlet.ShouldProcess($obj)) { 'hello' }
}
Test-ShouldProcess
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/444154.html
