在 Powershell 中获取当前用户的凭据对象而不提示

发布于 2024-09-27 07:40:01 字数 650 浏览 9 评论 0原文

我有一个 Powershell 脚本,将通过自动化工具针对多个服务器运行。

它在 Windows 计算机上运行良好,因为远程调用使用该工具的服务帐户,无需在代码中提示或公开任何凭据。

该脚本还可以使用 SharpSSH 包通过 SSH 在 Linux 计算机上运行。 SharpSSH 不会自动使用 Powershell 用户的凭据,但需要用户名和密码、RSA 密钥文件或 PSCredential 对象。

我无法使用 Get-Credential 提示输入凭据,因为它是通过自动化工具运行的。我不想在代码中暴露用户名和密码,也不想有 RSA 密钥。我想从当前 Powershell 用户(服务帐户)构造一个 PSCredential 对象。

尝试 [System.Net.CredentialCache]::DefaultNetworkCredentials 显示空白,并且 [System.Security.Principal.WindowsIdentity]::GetCurrent() 不提供该对象或我需要的信息。

有人有从当前用户创建 PSCredential 对象的方法吗?或者也许有一个完全不同的替代方案来解决这个问题?

非常感谢!

I have a Powershell script that is going to be run through an automation tool against multiple servers.

It works fine on Windows machines, as the remote calls use the tool's service account without any need for prompting or exposing any credentials in code.

This script also runs against Linux machines via SSH using the SharpSSH package. SharpSSH does not automatically use the Powershell user's credentials but requires either a username and password, an RSA key file, or a PSCredential object.

I can't prompt for credentials using Get-Credential, because it's being run through the automation tool. I don't want to expose the username and password in code or have an RSA key sitting out there. I would like to construct a PSCredential object from the current Powershell user (the service account).

Trying [System.Net.CredentialCache]::DefaultNetworkCredentials shows a blank, and [System.Security.Principal.WindowsIdentity]::GetCurrent() doesn't provide the object or information I need.

Does anyone have a method for creating a PSCredential object from the current user? Or maybe a completely different alternative for this problem?

Many thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

画▽骨i 2024-10-04 07:40:01

Windows API 不会公开您需要的信息,这就是 Powershell 无法获取它们的原因。这是安全子系统的一个有意的功能。实现此目的的唯一方法是让 Linux 计算机信任调用计算机,例如将它们加入 Active Directory(或任何真正的 kerberos 设置)。

除此之外,您需要以某种方式存储和传递这些信息。

您可以将 RSA 密钥存储在用户的密钥库中,并在运行时提取它(使用 .NET Crypto/Keystore 库),这样您就不会将密钥与代码一起存储。这样,密钥本身将受到操作系统的保护,并且仅当调用用户经过身份验证时才可用。您还需要安装一件东西,但这可能是实现您目标的唯一方法。

The Windows API will not expose the information you need, which is why Powershell can't get to them. Its an intentional feature of the security subsystem. The only way for this to work is for the Linux machines to trust the calling machine, such as joining them to an Active Directory (or any kerberos setup really).

Aside from that, you'd need to store and pass this information somehow.

You could store the RSA key in the user's keystore and extract it at runtime (using the .NET Crypto/Keystore libs), so you aren't storing the key around with the code. That way the key itself would be protected by the OS and available only when the calling user was authenticated. You'd have one more thing to install, but may be the only way to achieve what you are aiming for.

荒岛晴空 2024-10-04 07:40:01

由于您可以从凭证对象中以明文形式获取密码,因此我怀疑您是否可以在没有提示的情况下获取该密码。

Since you can get the password in plaintext from a credential object, I doubt you can get this without prompting.

挽梦忆笙歌 2024-10-04 07:40:01

使用服务帐户的加密密钥对密码进行加密怎么样?

一个简单的示例:

作为服务帐户运行 PowerShell,运行以下命令并将输出保存到文本文件(或将其嵌入到计划任务调用中):

$String = '<PASSWORD>'
ConvertFrom-SecureString -SecureString (ConvertTo-SecureString -String $String -AsPlainText -Force)

来解密和使用密码:

 $EncryptedString = '<ENCRYPTED PASSWORD FROM ABOVE>'
 [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((ConvertTo-SecureString -String $EncryptedString)))

在计划任务中使用以下命令 应该可以解决问题。但是,您不能在另一台计算机上重复使用加密密码,或者如果您出于某种原因破坏了本地密钥存储:)

How about encrypting the password using the service account's encryption key?

A quick example:

Run PowerShell as the service account, run the following and save the output to a text file (or embed it in the scheduled task call):

$String = '<PASSWORD>'
ConvertFrom-SecureString -SecureString (ConvertTo-SecureString -String $String -AsPlainText -Force)

Use the following in your scheduled task in order to decrypt and utilize the password:

 $EncryptedString = '<ENCRYPTED PASSWORD FROM ABOVE>'
 [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((ConvertTo-SecureString -String $EncryptedString)))

That should do the trick. You cannot reuse the encrypted password on a different computer, though, or if you for whatever reason destroy you local key store :)

落在眉间の轻吻 2024-10-04 07:40:01

“尝试 [System.Net.CredentialCache]::DefaultNetworkCredentials 显示空白,并且 [System.Security.Principal.WindowsIdentity]::GetCurrent() 未提供我需要的对象或信息。”

你已经有了答案。我使用它在多个脚本中传递当前登录用户的凭据:

$Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$Username = $Credentials.UserName
$Password = $Credentials.Password

如果您尝试将它们转储到任何类型的可读输出,则当您转储它们时这些值是空的(出于明显的安全原因),但是它们确实可以在您的位置工作需要一个 PSCredential 对象。

"Trying [System.Net.CredentialCache]::DefaultNetworkCredentials shows a blank, and [System.Security.Principal.WindowsIdentity]::GetCurrent() doesn't provide the object or information I need."

You already have your answer. I use this to pass the currently logged in user's credentials along in several scripts:

$Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$Username = $Credentials.UserName
$Password = $Credentials.Password

If you try to dump them to any kind of readable output, those values are empty when you dump them (for obvious security reasons), however they do work where you need a PSCredential object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文