你好,我是新的开发脚本在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.
为什么会发生这种情况,我该如何解决?
我提前感谢你的贡献
这是一个范围问题。ScriptBlock
不能直接引用在另一个PowerShell会话中定义的变量。在远程操作或依赖作业时使用新会话。在PSRemoting时,New-PSSession
、Enter-PSSession
等的存在和使用暗示了这一点,但在使用作业时则不那么明显。
您可以在ScriptBlock
中的变量引用前面加上$using:
,以便"使用"。在调用会话中定义的变量:
{
Set-ADAccountPassword -Identity $using:user -Reset -NewPassword $using:pass
}
但是,当在本地系统上运行ScriptBlock
时,不能使用using
作用域。如果在同一会话中本地执行ScriptBlock
,引用局部变量将工作得很好(使用调用操作符&
,Invoke-Command
通常不建议在本地使用,因为它不必要地依赖于PSRemoting
)。那么如果我们想让在任何地方运行呢?
如果ScriptBlock
需要能够在不考虑执行上下文的情况下运行,则可以使用Invoke-Command
的-ArgumentList
参数(这也适用于Start-Job
等cmdlet,当执行将在本地但在新会话中执行时)将变量传递给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
的名称不需要与父作用域中的原始变量名称相同。