Сценарий PowerShell запускается из оболочки, но не из моего приложения - PullRequest
9 голосов
/ 15 марта 2011

Я пытаюсь создать приложение Windows, которое сможет запускать различные сценарии Powershell.

У меня есть сценарий, который работает как надо (при запуске из приглашения 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 ]

1 голос
/ 07 мая 2011

Похоже, вы просто создаете пользователя в AD.Имея код c #, вызывающий скрипт powershell, вы добавляете в свой сценарий еще одну движущуюся часть.Почему бы не вызвать его прямо в коде C #.Проверьте эту статью MSDN .

0 голосов
/ 13 августа 2011

При запуске из C # я обнаружил, что мне нужно добавить оснастку PowerShell «Microsoft.Windows.AD», прежде чем я смогу запустить предоставляемый им командлет.

0 голосов
/ 22 апреля 2011

Похоже, что Runspace в приложении создается с ограничением RunspaceConfiguration, поэтому он не может найти System.DirectoryServices для нужных вам функций AD.

Что выполучить, когда вы запускаете в своем приложении следующее?

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.Бит [AppDomain]::CurrentDomain.GetAssemblies() показывает 16, когда я запускаю его в командной строке vanilla.System.DirectoryServices отображается во всех трех списках.

0 голосов
/ 16 марта 2011

Проблема заключается в том, что метод Create в вашем объекте ADSI, $ou, не существует.Я бы проверил, что он создается правильно.Запустите сценарий за пределами приложения, чтобы убедиться, что он работает, или добавьте дополнительную строку, отображающую его членов:

$ou | Get-Member
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...