脚本可以在powershell中工作,但不能在c#中工作
本文关键字:工作 但不能 powershell 脚本 | 更新日期: 2023-09-27 18:17:34
此脚本在PowerShell ISE中运行时有效(它在Active Directory中设置给定用户的远程桌面服务配置文件设置):
Get-ADUser FirstName.LastName | ForEach-Object {
$User = [ADSI]"LDAP://$($_.DistinguishedName)"
$User.psbase.invokeset("TerminalServicesProfilePath","''Server'Share'HomeDir'Profile")
$User.psbase.invokeset("TerminalServicesHomeDrive","H:")
$User.psbase.invokeset("TerminalServicesHomeDirectory","''Server'Share'HomeDir")
$User.setinfo()
}
但是当我尝试从c#应用程序运行它时,我得到了我调用的每个invokeset
的错误:
调用InvokeSet"与"2";论点(s):
"未知的名字。(Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"
下面是代码,这是在我的PowerShell
类:
public static List<PSObject> Execute(string args)
{
var returnList = new List<PSObject>();
using (var powerShellInstance = PowerShell.Create())
{
powerShellInstance.AddScript(args);
var psOutput = powerShellInstance.Invoke();
if (powerShellInstance.Streams.Error.Count > 0)
{
foreach (var error in powerShellInstance.Streams.Error)
{
Console.WriteLine(error);
}
}
foreach (var outputItem in psOutput)
{
if (outputItem != null)
{
returnList.Add(outputItem);
}
}
}
return returnList;
}
我这样称呼它:
var script = $@"
Get-ADUser {newStarter.DotName} | ForEach-Object {{
$User = [ADSI]""LDAP://$($_.DistinguishedName)""
$User.psbase.invokeset(""TerminalServicesProfilePath"",""''file'tsprofiles$'{newStarter.DotName}"")
$User.psbase.invokeset(""TerminalServicesHomeDrive"",""H:"")
$User.psbase.invokeset(""TerminalServicesHomeDirectory"",""''file'home$'{newStarter.DotName}"")
$User.setinfo()
}}";
PowerShell.Execute(script);
其中newStarter.DotName
为已存在AD用户的帐号名。
我尝试在C#
脚本的顶部包含Import-Module ActveDirectory
,但没有效果。我还在正常运行的脚本和C#
脚本中调用$PSVersionTable.PSVersion
,并且都返回版本3正在使用。
将属性名更新为
后msTSProfilePath
msTSHomeDrive
msTSHomeDirectory
msTSAllowLogon
我在c#中得到这个错误:
异常调用"setinfo"与"0";参数:"指定给目录服务的属性语法无效。
在PowerShell中查询这些属性什么也没有(没有错误但也没有输出)
有人知道是什么原因引起的吗?
多谢
更新答案:这些属性似乎在2008+中不存在。试试下面这些:
- msTSAllowLogon
- msTSHomeDirectory
- msTSHomeDrive
- msTSProfilePath
请参阅本帖的完整解释。
原始答:
Abhijith pk的评论可能是答案。你需要运行Import-Module ActiveDirectory
,就像你需要在PowerShell命令行中做的那样。
如果你曾经在PowerShell命令行中运行过Import-Module ActiveDirectory
,你就会知道它需要一段时间来加载。在c#中运行时也是一样的。因此,如果您将在应用程序中运行几个AD命令,您最好将Runspace对象保持为静态对象并重用它,这意味着您只加载ActiveDirectory模块一次。
这里有关于如何在c#中做到这一点的细节:https://blogs.msdn.microsoft.com/syamp/2011/02/24/how-to-run-an-active-directory-ad-cmdlet-from-net-c/
特别地,这是代码:
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[] { "activedirectory" });
Runspace myRunSpace = RunspaceFactory.CreateRunspace(iss);
myRunSpace.Open();