无法使用 System.automation.management(Power shell 包)in.Net 控制台应用



嗨,我正在创建一个软件,它应该注销除当前登录的Windows 10系统中的用户之外的所有内容。 我可以在powershell中使用powershell命令登录。在下面查找命令:

quser | Select-String "Disc" | ForEach{logoff ($_.toString() -split ' +')[2]}

上面的命令非常适合Powershell控制台。

当它添加到我的代码 c# 中并调用该命令时,它不起作用。请在下面找到代码。

string logOff = "quser | Select-String "Disc" | ForEach{logoff ($_.toString() -split ' +')[2]}";
PowerShell psExec = PowerShell.Create();
psExec.AddScript(logoff);
Collection<PSObject> results;
results = psExec.Invoke();

我也尝试过通过生成电源外壳的子进程。请检查以下代码:

processInfo = new ProcessStartInfo
{
UseShellExecute = false,
FileName = "powershell.exe",
Arguments = "quser | Select-String "Disc" | ForEach{logoff ($_.toString() -split ' +')[2]}"
}
Console.WriteLine("Starting child process...");
using (var process = Process.Start(processInfo))
{
process.WaitForExit();
}

我也尝试了如下:

using (PowerShell ps = PowerShell.Create())
{
ps.AddScript("‪C:\Users\vijay.rm\Desktop\test.ps1");
Collection<PSObject> PSOutput = ps.Invoke();
foreach (PSObject item in PSOutput)
{
if (item == null)
{
Console.WriteLine(item.BaseObject.ToString());
Console.WriteLine("Done");
}
}
}

其中 test.ps1 脚本包含:

quser | Select-String "Disc" | ForEach{logoff ($_.toString() -split ' +')[2]}

我还通过将其更改为 x86 和 x64 来检查构建,但结果是相同的。

我没有得到任何例外。

但我也没有让用户注销。

我还尝试了具有管理权限的控制台应用程序。

我希望在运行 c# 代码时,除登录计算机的用户之外的所有用户都应该注销。 为了检查用户是否注销的天气,请在powershell中运行以下命令:

Get-WMIObject -class Win32_UserProfile

你会得到如下的结果:


__GENUS                          : 2
__CLASS                          : Win32_UserProfile
__SUPERCLASS                     :
__DYNASTY                        : Win32_UserProfile
__RELPATH                        : Win32_UserProfile.SID="S-1-5-21-329068152-1454471165-1417001333-8355646"
__PROPERTY_COUNT                 : 29
__DERIVATION                     : {}
__SERVER                         : BDC3-LX-G5N6QQ2
__NAMESPACE                      : rootcimv2
__PATH                           : \BDC3-LX-G5N6QQ2rootcimv2:Win32_UserProfile.SID="S-1-5-21-329068152-1454471165-14
17001333-8355646"
AppDataRoaming                   : System.Management.ManagementBaseObject
Contacts                         : System.Management.ManagementBaseObject
Desktop                          : System.Management.ManagementBaseObject
Documents                        : System.Management.ManagementBaseObject
Downloads                        : System.Management.ManagementBaseObject
Favorites                        : System.Management.ManagementBaseObject
HealthStatus                     : 3
LastAttemptedProfileDownloadTime :
LastAttemptedProfileUploadTime   :
LastBackgroundRegistryUploadTime :
LastDownloadTime                 :
LastUploadTime                   :
LastUseTime                      : 20190917044128.412000+000
Links                            : System.Management.ManagementBaseObject
Loaded                           : True
LocalPath                        : C:Usersvijay.rm
Music                            : System.Management.ManagementBaseObject
Pictures                         : System.Management.ManagementBaseObject
RefCount                         :
RoamingConfigured                : False
RoamingPath                      :
RoamingPreference                :
SavedGames                       : System.Management.ManagementBaseObject
Searches                         : System.Management.ManagementBaseObject
SID                              : S-1-5-21-329068152-1454471165-1417001333-8355646
Special                          : False
StartMenu                        : System.Management.ManagementBaseObject
Status                           : 0
Videos                           : System.Management.ManagementBaseObject
PSComputerName                   : BDC3-LX-G5N6QQ2

当我们运行脚本或代码时,加载的属性应该为 false。

提前谢谢。

最有可能失败的是调用外部程序quser.exelogoff.exe(可能是后者 - 我强烈怀疑您需要运行管理权限才能注销其他用户的会话(。

外部程序输出的 stderr 消息显示在 PowerShell 的错误流中,但它们不会导致异常因此代码会以静默方式运行和失败。
(同样,报告非零退出代码的外部程序会导致 PowerShell 执行任何操作。

要查看出了什么问题,您必须检查psExec.Streams.Error,即在呼叫期间收集的错误消息。


在评论中,您指出在检查错误流时,您发现那里的错误消息抱怨quser找不到作为命令(The term 'quser' is not recognized as the name of a cmdlet, function, script file, or operable program. ...(。

这表明了两个可能的原因之一(结果是(a((:

  • (a(:您的System32文件夹(通常为C:WindowsSystem32(莫名其妙地未列在您的Path环境变量($env:Path(中,但这是非常不寻常的,值得进一步调查。

    • 作为同时的解决方法:虽然您可以尝试引用quser.exe并按其完整路径logoff.exe,但它使您可以更灵活地将 System32 文件夹作为第一个命令添加到$env:PATH
string logOff = "$env:PATH += ";$env:windir\System32"; quser.exe | Select-String "Disc" | ForEach{logoff.exe ($_.toString() -split ' +')[2]}";
  • 或 (b(:C# 代码使用 32 位版本的 PowerShell SDK,并且在32 位应用程序视为C:WindowsSystem32的不同目录中(实际上是C:WindowsSysWow64(,quser.exe也不存在logoff.exe

    • 您可以尝试调用64 位版本,方法是通过虚拟目录[1]C:WindowsSysNative显式引用它们(仅对 32 位应用程序可见(:
string logOff = "C:\Windows\SysNative\quser.exe | Select-String "Disc" | ForEach{C:\Windows\SysNative\logoff.exe ($_.toString() -split ' +')[2]}";

[1] 注意:我假设您的 Windows 安装的根目录是C:Windows; 即使它位于不同名称的目录中,也可以可靠地引用它的方法是使用$env:windir而不是文字C:Windows

最新更新