脚本可以在Powershell中运行,但不能在C#中运行 [英] Script works in powershell but not c#

查看:88
本文介绍了脚本可以在Powershell中运行,但不能在C#中运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此脚本在PowerShell ISE中运行时起作用(它在Active Directory中设置给定用户的远程桌面服务配置文件设置):

This script works when running in PowerShell ISE (it sets the given user's Remote Desktop Services Profile settings in 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 都会出错:

But when I try running it from a C# application I get an error for each invokeset that I call:


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

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

未知名称。(HRESULT的异常:0x80020006(DISP_E_UNKNOWNNAME) )

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

这是代码,它位于我的 PowerShell 类中:

Here is the code, which is inside my 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用户的帐户名。

Where newStarter.DotName contains the (already existing) AD user's account name.

我尝试在顶部添加 Import-Module ActveDirectory C#脚本,但无效。我还在正常运行的脚本和 C#脚本中都调用了 $ PSVersionTable.PSVersion ,两者均返回版本3为正在使用。

I tried including Import-Module ActveDirectory at the top of the C# script, but with no effect. I also called $PSVersionTable.PSVersion in both the script running normally and the C# script and both return that version 3 is being used.

将属性名称更新为

msTSProfilePath
msTSHomeDrive
msTSHomeDirectory
msTSAllowLogon

我在C#中遇到此错误:

I am getting this error in C#:


使用 0参数调用 setinfo的异常:指定的属性语法

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

然后在PowerShell中查询这些属性没有问题(没有错误,也没有输出)

And querying those properties in PowerShell nothing (no error but also no output)

有人碰巧知道是什么原因吗?

Does anyone happen to know what could cause this?

非常感谢

推荐答案

更新后的答案:似乎这些属性在2008+中不存在,请尝试使用这些属性:

Updated answer: It seems that these attributes don't exist in 2008+. Try these ones instead:


  • msTSAllowLogon

  • msTSHomeDirectory

  • msTSHomeDrive

  • msTSProfilePath

  • msTSAllowLogon
  • msTSHomeDirectory
  • msTSHomeDrive
  • msTSProfilePath

请参阅查看完整的解释。

See the answer in this thread for the full explanation.

原始答案:

来自 Abhijith pk 的评论可能是答案。您需要运行 Import-Module ActiveDirectory ,就像您需要在命令行PowerShell中一样。

The comment from Abhijith pk is probably the answer. You need to run Import-Module ActiveDirectory, just like you need to do in the command line PowerShell.

如果您曾经在PowerShell命令行中运行 Import-Module ActiveDirectory ,就会知道加载需要一段时间。在C#中运行时将相同。因此,如果您将在应用程序中运行多个AD命令,则最好将Runspace对象作为静态对象保持活动状态并重用它,这意味着您只需加载ActiveDirectory模块一次。

If you've ever run Import-Module ActiveDirectory in the PowerShell command line, you'll know it takes a while to load. It will be the same when run in C#. So if you will be running several AD commands in your application, you would be better off keeping a Runspace object alive as a static object and reuse it, which means you only load the ActiveDirectory module once.

这里有有关如何在C#中执行此操作的详细信息:
> https://blogs.msdn.microsoft.com/syamp/2011/02/24/how-to -run-an-active-directory-ad-cmdlet-from-net-c /

There is details here about how to do that in 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();

这篇关于脚本可以在Powershell中运行,但不能在C#中运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆