在C#程序中嵌入授权凭据执行PowerShell命令的问题咨询
问题描述
我用VS C#编写了一个Windows应用程序,点击Button3时会执行一段PowerShell命令,用于获取远程机器的开机时长。右键以管理员身份运行(输入授权用户信息)时命令可正常执行,但以无PowerShell执行权限的普通标准用户身份运行时会报错。想知道能否在程序中嵌入授权用户名和密码,无需右键以管理员身份运行即可正常执行该命令?
原代码如下:
private void button3_Click_2(object sender, EventArgs e) { string command = string.Concat(@"$wmi = Get-WmiObject -class Win32_OperatingSystem -computer ", txb_pc.Text.Trim(), "\n", "$LBTime = $wmi.ConvertToDateTime($wmi.Lastbootuptime)","\n", "[TimeSpan]$uptime = New-TimeSpan $LBTime $(get-date)","\n", "\"$($uptime.days) Gun $($uptime.hours) Saat $($uptime.minutes) Dakika\""); using (PowerShell powerShell = PowerShell.Create()) { powerShell.AddScript(command); powerShell.AddCommand("Out-String"); Collection<PSObject> PSOutput = powerShell.Invoke(); StringBuilder stringBuilder = new StringBuilder(); foreach (PSObject pSObject in PSOutput) stringBuilder.AppendLine(pSObject.ToString()); txb_islemmonitoru.Text = stringBuilder.ToString(); } }
解决方案
可以通过在PowerShell执行上下文注入管理员凭据的方式实现,无需手动以管理员身份运行程序。以下是两种可行方案:
方案1:在PowerShell命令中直接传入凭据
修改PowerShell命令,加入-Credential参数,同时在C#代码中构建管理员凭据并注入命令:
private void button3_Click_2(object sender, EventArgs e) { // 替换为实际管理员账号信息(域账号格式:DOMAIN\AdminUser,本地账号:MachineName\AdminUser) string adminUsername = "DOMAIN\\AdminUser"; string adminPassword = "YourAdminPassword"; // 构建带凭据的PowerShell命令 string command = string.Concat( "$securePassword = ConvertTo-SecureString '", adminPassword, "' -AsPlainText -Force\n", "$credential = New-Object System.Management.Automation.PSCredential('", adminUsername, "', $securePassword)\n", "$wmi = Get-WmiObject -class Win32_OperatingSystem -computer ", txb_pc.Text.Trim(), " -Credential $credential\n", "$LBTime = $wmi.ConvertToDateTime($wmi.Lastbootuptime)\n", "[TimeSpan]$uptime = New-TimeSpan $LBTime $(get-date)\n", "\"$($uptime.days) Gun $($uptime.hours) Saat $($uptime.minutes) Dakika\""); using (PowerShell powerShell = PowerShell.Create()) { powerShell.AddScript(command); powerShell.AddCommand("Out-String"); Collection<PSObject> PSOutput = powerShell.Invoke(); // 处理执行错误 if (powerShell.HadErrors) { StringBuilder errorBuilder = new StringBuilder(); foreach (var error in powerShell.Streams.Error) { errorBuilder.AppendLine("错误:" + error.ToString()); } txb_islemmonitoru.Text = errorBuilder.ToString(); return; } StringBuilder stringBuilder = new StringBuilder(); foreach (PSObject pSObject in PSOutput) stringBuilder.AppendLine(pSObject.ToString()); txb_islemmonitoru.Text = stringBuilder.ToString(); } }
方案2:通过C#直接创建PSCredential绑定到PowerShell会话
这种方式更符合C#编程习惯,避免在字符串中拼接敏感信息:
private void button3_Click_2(object sender, EventArgs e) { string adminUsername = "DOMAIN\\AdminUser"; string adminPassword = "YourAdminPassword"; string targetComputer = txb_pc.Text.Trim(); // 创建安全字符串形式的密码 SecureString securePassword = new SecureString(); foreach (char c in adminPassword) { securePassword.AppendChar(c); } PSCredential credential = new PSCredential(adminUsername, securePassword); using (PowerShell powerShell = PowerShell.Create()) { // 添加WMI命令及参数 powerShell.AddCommand("Get-WmiObject") .AddParameter("Class", "Win32_OperatingSystem") .AddParameter("ComputerName", targetComputer) .AddParameter("Credential", credential); Collection<PSObject> wmiResults = powerShell.Invoke(); // 处理错误 if (powerShell.HadErrors) { StringBuilder errorBuilder = new StringBuilder(); foreach (var error in powerShell.Streams.Error) { errorBuilder.AppendLine("错误:" + error.ToString()); } txb_islemmonitoru.Text = errorBuilder.ToString(); return; } // 计算并显示开机时长 if (wmiResults.Count > 0) { var wmiObj = wmiResults[0]; DateTime lastBootTime = System.Management.ManagementDateTimeConverter.ToDateTime( wmiObj.Properties["LastBootUpTime"].Value.ToString() ); TimeSpan uptime = DateTime.Now - lastBootTime; txb_islemmonitoru.Text = $"{uptime.Days} Gun {uptime.Hours} Saat {uptime.Minutes} Dakika"; } else { txb_islemmonitoru.Text = "未获取到目标机器的开机时间信息"; } } }
关键安全注意事项
- 禁止明文存储密码:示例中为演示使用了明文密码,实际开发中必须对密码进行加密存储(如使用DPAPI加密、Windows凭据管理器存储),运行时再解密使用,防止管理员账号信息泄露。
- 确认权限配置:确保所用的管理员账号拥有访问目标机器WMI服务的权限,否则即使传入正确凭据也会执行失败。
内容的提问来源于stack exchange,提问作者Hakan DAŞTAN
相关产品推荐
相关产品推荐

