如何在远程 Powershell 会话中保留凭据?

如何在远程 Powershell 会话中保留凭据?

我有一个 Azure 文件共享,并希望在我的 Azure VM 中使用它 - 在使用 cmdkey 将凭据保留在 VM 上并使用 net use 进行安装之后。通过在 Windows Server 2012 R2 上的本地 Powershell 会话中运行这些命令进行了测试。

但我需要将此步骤添加到 Azure 部署脚本中。 Azure Powershell 脚本从我的笔记本电脑运行,连接到 Azure 订阅并使用大量变量从头开始构建虚拟机。

弄清楚如何使用 Invoke-Command 将变量从 Azure Powershell 脚本传递到新创建的 VM 上的远程 Powershell 会话。

$Session = New-PSSession -ConnectionUri $Uri -Credential $DomainCredential

$ScriptBlockContent = { 
Param ($Arg1,$Arg2,$Arg3)
cmdkey /add:$Arg1 /user:$Arg2 /pass:$Arg3}

Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($Share,$AccountName,$Key)

错误如下:

PS C:\> Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($Share,$AccountName,$Key)
CMDKEY: Credentials cannot be saved from this logon session.

替换为cmdkey /list来检查语法,没有错误。

PS C:\> Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent
Currently stored credentials:
* NONE *

Windows 更新 PowerShell 模块(Invoke-WUInstall)也存在类似问题(无法修复),它在 VM 上的本地 Powershell 会话中运行良好,但通过远程 Powershell 启动时不会更新。

有什么办法可以解决这个问题吗?

答案1

由于 Windows 处理身份验证的方式,无法使用 CMDKEY 通过远程 PowerShell 会话设置凭据,而必须在使用 CMDKEY 时以交互方式完成。

去引用唐·琼斯来自寻找与您的答案类似的答案的帖子:

这是 Cmdkey 命令的限制 - 并不是 PowerShell 的问题。但它与 Remotig 处理凭据的方式有关。远程会话实际上并没有获得凭据,而是获得了委托票证,因此实际上没有要保存的令牌。这都是设计使然,您无法重新配置。

答案2

您可以使用 Sysinternal 的执行程序如果您不想使用计划任务。通常,当您启动 PowerShell 会话时,它会在进程中运行services(您可以通过query session在远程计算机上运行命令来确认这一点),而不是在 cmdkey 失败的本地用户中运行。

为了解决这个问题,我们需要在本地用户进程中运行 cmdkey.exe,这可以通过使用PsExec.exe's -i标志来实现

运行该程序,使其与远程系统上指定会话的桌面进行交互。如果未指定会话,则进程在控制台会话中运行。

现在,挑战是获取远程计算机上本地用户的会话 ID。我通过运行query session命令实现了此目的,该命令提供了计算机上活动的会话列表。其中一个可能的解决方案是 -

$processId = Invoke-Command $session -ScriptBlock  {
param($user)
    $sessions = query session $user;
    return $sessions[1].split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)[2];

} -ArgumentList ($user)

这里$user包含远程计算机上本地用户的用户名。

获得会话 ID 后,你可以简单地执行

PsExec \\<computer_name> -u <local_user_name> -p <password> -h -i $processId cmdkey.exe /generic:testtt /user:userr /pass:pass

笔记:

  1. 有更好的方法来获取远程机器上的用户的会话 ID。
  2. 现在,在运行 PsExec 时,我再次与可以避免的远程系统建立连接(我还没有测试过)。
  3. 运行该命令的用户应该在远程机器上具有管理员访问权限。

相关内容