脚本在 powershell 中有效,但在 c# 中无效

Script works in powershell but not c#

此脚本在 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 都会出错:

Exception calling "InvokeSet" with "2" argument(s):

"Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"

这是代码,在我的里面 PowerShell class:

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 return。


将 属性 名称更新为

msTSProfilePath
msTSHomeDrive
msTSHomeDirectory
msTSAllowLogon

我在 C# 中遇到此错误:

Exception calling "setinfo" with "0" argument(s): "The attribute syntax specified to the directory service is invalid.

并且在 PowerShell 中查询这些属性没有任何问题(没有错误但也没有输出)


有没有人碰巧知道是什么原因造成的?

非常感谢

更新答案:这些属性似乎在 2008+ 中不存在。试试这些:

  • msTSAllowLogon
  • msTSHomeDirectory
  • msTSHomeDrive
  • msTSProfilePath

请参阅 this thread 中的答案以获得完整解释。

原答案:

来自 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();