【问题标题】:Script works in powershell but not c#脚本适用于 powershell 但不适用于 c#
【发布时间】:2017-03-25 23:29:45
【问题描述】:

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

使用“2”个参数调用“InvokeSet”的异常:

“未知名称。(来自 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# 中遇到此错误:

使用“0”参数调用“setinfo”的异常:“指定给目录服务的属性语法无效。

并且在 PowerShell 中什么也不查询这些属性(没有错误但也没有输出)


有谁知道这是什么原因造成的?

非常感谢

【问题讨论】:

  • 尝试在您在 c# 中运行的脚本中添加 import-module for ad。
  • @Abhijithpk 刚刚尝试将Import-Module ActiveDirectory 添加到脚本中,但仍然看到相同的错误

标签: c# powershell active-directory terminal-services


【解决方案1】:

更新的答案:这些属性似乎在 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();

【讨论】:

  • 您好,Gabriel 感谢您的回答。我尝试在脚本顶部包含Import-Module ActiveDirectory,但我仍然看到同样的错误。你知道还有什么可能导致这种情况吗?
  • 我已经更新了我的答案。如果您的 AD 在 Windows Server 2008+ 上运行,您可能需要查看不同的属性。
  • 谢谢,我会试一试。这是否可能是适合他在 PowerShell 内部工作的相同命令的问题? (仍在联系同一个服务器)
  • 是的。现在我在办公室,我自己尝试了一下,使用“TerminalServicesProfilePath”时遇到了同样的“未知名称”错误,但它适用于“msTSProfilePath”。
  • 我更改了属性名称,但现在我看到了这个错误:Exception calling "setinfo" with "0" argument(s): "The attribute syntax specified to the directory service is invalid.我更新了我的问题
猜你喜欢
  • 2012-08-04
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 2015-04-14
  • 2021-10-27
相关资源
最近更新 更多