使用带有凭据的调用命令时,凭据参数未正确初始化

问题描述 投票:0回答:1

所以我尝试使用和不使用凭据调用以下代码。

$username = "user"
$password = "password"
$cred = new-object -argumentlist $username, $password

#Invoke-Command -ComputerName computer -FilePath "C:\Some\Path.ps1" -Credential $cred
Invoke-Command -ComputerName localhost -FilePath "C:\Some\Path.ps1"

调用cmd后出现以下几行:

命令管道位置 1 处的 cmdlet New-Object 提供以下参数的值: 类型名称:

由于我不知道这个参数指的是什么,所以我输入一个字母,然后出现以下错误:

new-object : 找不到类型 [;]: 验证包含此类型的程序集是否已加载。 在 C:\Some\Path.ps1:8 字符:9

  • $cred = new-object -argumentlist $用户名,$密码
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo:无效类型:(:) [新对象],PSArgumentException
    • FullyQualifiedErrorId:TypeNotFound、Microsoft.PowerShell.Commands.NewObjectCommand

[localhost] 连接到远程服务器 localhost 失败,并显示以下错误消息:访问被拒绝。了解更多 有关信息,请参阅 about_Remote_Troubleshooting 帮助主题。 + 类别信息:OpenError:(localhost:字符串)[],PSRemotingTransportException + FullQualifiedErrorId :访问被拒绝,PSSessionStateBroken

我有腹肌,不知道这意味着什么。有人可以帮我吗?

powershell invoke-command
1个回答
1
投票

不用担心 - PowerShell 是一种异常复杂的语言运行时,最初的学习曲线可能相当陡峭:)

在 .NET 中 - PowerShell 构建于其之上的运行时框架 - 所有对象都有一个 type - 因此您需要在创建对象时指定所需的对象类型。

要找到适当的类型名称,我们首先看一下将对象作为参数传递给的

-Credential
参数。我们可以使用
Get-Help <commandName> -Parameter <parameterName>
来检查参数定义:

PS ~> Get-Help Invoke-Command -Parameter Credential

-Credential <pscredential>

    Required?                    false
    Position?                    Named
    Accept pipeline input?       true (ByPropertyName)
    Parameter set name           ComputerName, Uri, FilePathComputerName, FilePathUri, VMId, VMName, FilePathVMId, FilePathVMName
    Aliases                      None
    Dynamic?                     false

在第一行,我们看到它需要一个类型为

pscredential
的值。

对于交互式脚本,构造

pscredential
对象的最简单方法是使用
Get-Credential
命令
- 它会提示您输入密码并返回
pscredential
对象,然后您可以将其传递给
Invoke-Command
(如果需要的话稍后可以重复使用):

PS ~> $credential = Get-Credential -Username $username # this will prompt you for a password
Enter your credentials.
Password for user asd: ********

PS ~> Invoke-Command {...} -Credential $credential # now we can pass the credential object to the command parameter

假设目标计算机都属于同一域,并且您拥有的凭据有权连接到它们上的 WinRM 端点,您可以对所有目标计算机重复使用相同的凭据对象:

foreach ($computerName in $listOfComputerNames) {
  Invoke-Command -ComputerName $computerName -ScriptBlock { ... } -Credential $credential
}

...或者您可以一次性将所有计算机名称传递给

Invoke-Command

Invoke-Command -ComputerName $listOfComputerNames -ScriptBlock { ... } -Credential $credential

但是,对于无人值守的使用,您可能仍然需要找到一种无需

Get-Credential
即可实例化凭证对象的方法。

让我们尝试将正确的类型名称传递给

New-Object

PS ~> $cred = New-Object -TypeName pscredential -ArgumentList $username, $password

New-Object : Cannot find an overload for "PSCredential" and the argument count: "2".
At line:1 char:9
+ $cred = New-Object -TypeName pscredential -ArgumentList $username, $p ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

哦不!传递给

New-Object
的参数与
pscredential
类型定义的构造函数参数不匹配。

检查给定类型构造函数的所有重载签名的最简单方法是调用该类型的静态

new
方法,而不传递参数列表:

PS ~> [pscredential]::new

OverloadDefinitions
-------------------
pscredential new(string userName, securestring password)
pscredential new(psobject pso)

带有签名

pscredential new(string userName, securestring password)
的构造函数可能正是我们想要的 - 但它表示它需要一个
securestring
类型的对象而不是常规字符串。

要从纯文本实例化

[securestring]
,我们可以使用
ConvertTo-SecureString
cmdlet:

PS ~> $securePassword = $password |ConvertTo-SecureString -AsPlainText -Force
PS ~> $credential = New-Object pscredential -ArgumentList $username, $securePassword
PS ~> # yay, no more errors!
Ps ~> Invoke-Command {...} -Credential $credential

作为

New-Object
命令的替代方案,您还可以使用我们之前用于发现构造函数签名的静态
::new
方法:

PS ~> $credential = [pscredential]::new($username, $securePassword)
© www.soinside.com 2019 - 2024. All rights reserved.