PowerShell脚本从shell运行,但不是从我的应用程序运行

时间:2011-03-15 10:51:31

标签: c# powershell active-directory

我正在尝试创建一个能够运行各种Powershell脚本的Windows应用程序。

我有一个可以正常运行的脚本(从Powershell提示符运行时),我的Windows应用程序似乎按照它应该执行它,但它无法在我的OU上找到方法。

当我从Windows应用程序执行脚本时,我会收到这些消息:

  

错误:检索成员“创建”时发生以下异常:“那里    在服务器上没有这样的对象。   “

     

错误:检索成员“删除”时发生以下异常:“那里    在服务器上没有这样的对象。“

Powershell脚本:

function New-AdUser {

param (
    [string] $Username = $(throw "Parameter -Username [System.String] is required."),
    [string] $Password = $(throw "Parameter -Password [System.String] is required."),
    [string] $OrganizationalUnit = "Users",
    [string] $DisplayName,

    [string] $FirstName,

    [string] $LastName,

    [string] $Initials,
[string] $MobilePhone,
    [string] $Description,
    [switch] $CannotChangePassword,

    [switch] $PasswordNeverExpires,
    [switch] $Disabled

)

try {

    $currentDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()

    $dn = $currentDomain.GetDirectoryEntry().distinguishedName
    $ou = [ADSI] "LDAP://CN=$OrganizationalUnit,$dn"

    $userAccount = $ou.Create("user", "cn=$Username")

    $userAccount.SetInfo()



    $userAccount.userAccountControl = ($userAccount.userAccountControl.Item(0) -bxor 0x0002) #Enable the account

    $userAccount.SetInfo()


    $userAccount.sAMAccountName = $Username

    $userAccount.SetInfo()

    $userAccount.userPrincipalName = ("{0}@{1}" -f $Username, $currentDomain.Name)

    if ($DisplayName) {

        $userAccount.displayName = $DisplayName
    }

    if ($Description) {

        $userAccount.description = $Description
    }

    if ($FirstName) {

        $userAccount.givenName = $FirstName
    }


    if ($LastName) {
        $userAccount.SN = $LastName

    }


    if ($Initials) {

        $userAccount.initials = $Initials

    }



if ($MobilePhone) {
        $userAccount.mobile = $MobilePhone

}


    $userAccount.SetInfo()


    $userAccount.SetPassword($Password)

    # Password

    if ($PasswordNeverExpires) {

        $userAccount.userAccountControl = ($userAccount.userAccountControl.Item(0) -bxor 0x10000)
    }


    if ($CannotChangePassword) {
        $everyOne = [System.Security.Principal.SecurityIdentifier]'S-1-1-0'
        $EveryoneDeny = new-object System.DirectoryServices.ActiveDirectoryAccessRule ($Everyone,'ExtendedRight','Deny', [System.Guid]'ab721a53-1e2f-11d0-9819-00aa0040529b')
        $self = [System.Security.Principal.SecurityIdentifier]'S-1-5-10'
        $SelfDeny = new-object System.DirectoryServices.ActiveDirectoryAccessRule ($self,'ExtendedRight','Deny', [System.Guid]'ab721a53-1e2f-11d0-9819-00aa0040529b')

        $userAccount.get_ObjectSecurity().AddAccessRule($selfDeny)

       $userAccount.get_ObjectSecurity().AddAccessRule($EveryoneDeny)


       $userAccount.CommitChanges()
    }

    $userAccount.SetInfo()


    if ($Disabled) {
        $userAccount.userAccountControl = ($userAccount.userAccountControl.Item(0) -bxor 0x0002)

    }
    $userAccount.SetInfo()

} catch {

    Write-Error $_

    $ou.Delete("user", "cn=$Username")

    return $false

}

return $true

}

我拥有的C#代码是:

PowerShell ps = PowerShell.Create();

            ps.AddScript(GetScript("New-AdUser.ps1"));
            ps.Invoke();

            ps.AddCommand("New-AdUser").AddParameters(
                new List<CommandParameter>() {
                    new CommandParameter("Username", username),
                    new CommandParameter("Password", password),
                    new CommandParameter("FirstName", firstName),
                    new CommandParameter("LastName", lastName),
                    new CommandParameter("DisplayName", realName),
                    new CommandParameter("Initials", initials),
                    new CommandParameter("MobilePhone", mobilePhone),
                    new CommandParameter("OrganizationalUnit", "Users"),
                    new CommandParameter("PasswordNeverExpires")
                }
            );

            var results = ps.Invoke();

            foreach (var obj in results)
                Console.WriteLine(obj.ToString());

            if (ps.Streams.Error.Count > 0)
            {
                foreach (var err in ps.Streams.Error)
                    Console.WriteLine("ERROR: {0}", err.ToString());
            }

4 个答案:

答案 0 :(得分:1)

似乎您只是在AD中创建用户。通过让c#代码调用powershell脚本,您将在脚本中添加另一个移动部件。为什么不直接在C#代码中调用它。请查看此MSDN文章。

答案 1 :(得分:0)

问题似乎是ADSI对象上的Create方法$ou不存在。我会检查它是否正确创建。在应用程序外部运行脚本以确保它正常工作,或者有一个显示其成员的额外行:

$ou | Get-Member

答案 2 :(得分:0)

似乎应用程序中的Runspace似乎是使用限制性RunspaceConfiguration创建的,因此无法找到所需的AD功能的System.DirectoryServices。

在您的应用程序中运行以下内容后会得到什么?

string script = @"[AppDomain]::CurrentDomain.GetAssemblies()";
PowerShell ps = new PowerShell();
ps.AddScript(script);
var output = ps.Invoke();
foreach (var a in output.Select(pso => (System.Reflection.Assembly)pso.BaseObject))
    Console.WriteLine("Assembly: " + a.FullName);

当我在普通控制台应用程序中的调试器下运行时,我得到28个程序集(调试器外部19个),包括System.DirectoryServices。当我在vanilla命令提示符下运行时,[AppDomain]::CurrentDomain.GetAssemblies()位显示16。 System.DirectoryServices出现在所有三个列表中。

答案 3 :(得分:0)

从C#中运行时,我发现需要添加PowerShell管理单元“Microsoft.Windows.AD”才能运行它提供的cmdlet。