首页 > 解决方案 > PowerShell - 无法验证参数“身份”的参数。参数为空

问题描述

嗨,我是 powershell 和 Active Directory 中的新开发脚本,我正在尝试运行以下 .ps1

#! /usr/bin/pwsh

param ([String]$dns, [String]$adminUser, [String]$adminPassword, [String]$user, [String]$newPassword)

$password = ConvertTo-SecureString -String $adminPassword -AsPlainText -Force
$pass = ConvertTo-SecureString -String $newPassword -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($adminUser, $password)
$session = New-PSSession -cn $dns -Credential $credential -Authentication Negotiate
Invoke-Command -Session $session -ScriptBlock {Set-ADAccountPassword -Identity $user -Reset -NewPassword ($pass)}

像这样传递参数

./changePasswordAD.ps1 mydns myuser mypassword userToEdit NewPassword

得到的结果如下

Set-ADAccountPassword: Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.

为什么会发生这种情况,我该如何解决?

我提前感谢您的贡献

标签: powershellactive-directory

解决方案


这是一个范围问题。AScriptBlock不能直接引用在另一个 PowerShell 会话中定义的变量。远程处理或依赖作业时使用新会话。New-PSSessionPSRemoting 时,等的存在和使用暗示了这一点Enter-PSSession,但在使用作业时并不那么明显。

ScriptBlock您可以像这样在变量引用中添加前缀$using:,以便“使用”调用会话中定义的变量:

{
  Set-ADAccountPassword -Identity $using:user -Reset -NewPassword $using:pass
}

但是,在本地系统上运行时不能使用using范围。如果您在同一会话中本地执行本地变量,则ScriptBlock引用本地变量正常工作(使用调用运算符,通常不建议本地使用,因为它不必要地依赖)。那么如果我们想让它在任何地方运行呢?ScriptBlock&Invoke-CommandPSRemoting


如果ScriptBlock无论执行上下文如何都需要能够运行,您可以使用
-ArgumentList参数 of Invoke-Command(这也适用于 cmdlet,例如Start-Job当执行是本地的但在新会话中时)而不是将变量传递到ScriptBlock

Invoke-Command -ArgumentList $user, $pass {
  Param( $user, $pass )
  Set-ADAccountPassword -Identity $user -Reset -NewPassword $pass
}

我添加了换行符以提高可读性,但ScriptBlocks以上两者也应该用作单行。

注意:从技术上讲,通过 传递的参数-ArgumentList将按提供的顺序引用为$args[0],$args[1]等,例如在处理原始脚本参数时,但是在执行ScriptBlock类似于脚本的函数或...好吧,函数,添加该Param( .... )位将导致提供的参数分配给ScriptBlock;中定义的位置参数 在这种情况下,更友好的名称$user$pass. 这些param名称不需要与父作用域中的原始变量名称相同。


推荐阅读