问题描述
此脚本在 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","\ServerShareHomeDirProfile")
$User.psbase.invokeset("TerminalServicesHomeDrive","H:")
$User.psbase.invokeset("TerminalServicesHomeDirectory","\ServerShareHomeDir")
$User.setinfo()
}
但是当我尝试从 C# 应用程序运行它时,我会收到我调用的每个 invokeset
的错误:
But when I try running it from a C# application I get an error for each invokeset
that I call:
异常调用InvokeSet"与2"参数:
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 sprofiles${newStarter.DotName}"")
$User.psbase.invokeset(""TerminalServicesHomeDrive"",""H:"")
$User.psbase.invokeset(""TerminalServicesHomeDirectory"",""\filehome${newStarter.DotName}"")
$User.setinfo()
}}";
PowerShell.Execute(script);
其中 newStarter.DotName
包含(已经存在的)AD 用户的帐户名称.
Where newStarter.DotName
contains the (already existing) AD user's account name.
我尝试在 C#
脚本的顶部包含 Import-Module ActveDirectory
,但没有效果.我还在正常运行的脚本和 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#:
异常调用setinfo"与0"参数:为目录服务指定的属性语法无效.
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
请参阅 这个线程 以获得完整的解释.
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# 中无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!