Передача параметра С# в сценарий Powershell — невозможно проверить аргумент параметра «Идентификация»

Я пытаюсь написать приложение Windows Form на С#, которое выводит атрибуты AD для указанного пользователя. Я хочу, чтобы это работало так: пользователь вводит значение (имя пользователя) в текстовое поле, которое передается в качестве параметра сценарию Powershell, а вывод отображается в форме.

Мой код С# для создания параметра и вызова скрипта выглядит следующим образом:

private string RunScript(string scriptText)
    {
        // create Powershell runspace 
        Runspace runspace = RunspaceFactory.CreateRunspace();

        // open it 
        runspace.Open();

        RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);

        // create a pipeline and feed it the script text 
        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(scriptText);
        pipeline.Commands.Add(new Command("Set-ExecutionPolicy Unrestricted -Scope Process", true));

        // "Get-Process" returns a collection of System.Diagnostics.Process instances. 
        pipeline.Commands.Add("Out-String");

        //Create parameter and pass value to script
        String username = textBox3.Text;
        String scriptfile = @"c:\\scripts\\getpasswordexpirydate.ps1";
        Command myCommand = new Command(scriptfile, false);
        CommandParameter testParam = new CommandParameter("username", username);
        myCommand.Parameters.Add(testParam);

        pipeline.Commands.Add(myCommand);
        // execute the script
        Collection<PSObject> results = pipeline.Invoke();

        // close the runspace 
        runspace.Close();

        // convert the script result into a single string 
        StringBuilder stringBuilder = new StringBuilder();
        foreach (PSObject obj in results)
        {
            stringBuilder.AppendLine(obj.ToString());
        }

        // return the results of the script that has 
        // now been converted to text 
        return stringBuilder.ToString();
    }

Мой сценарий PowerShell выглядит следующим образом:

param([string]$username)

function Get-XADUserPasswordExpirationDate() {

Param ([Parameter(Mandatory=$true,  Position=0,  ValueFromPipeline=$true, HelpMessage="Identity of the Account")]

[Object] $accountIdentity)

PROCESS {

    $accountObj = Get-ADUser $accountIdentity -properties PasswordExpired, PasswordNeverExpires, PasswordLastSet

    if ($accountObj.PasswordExpired) {

        echo ("Password of account: " + $accountObj.Name + " already expired!")

    } else { 

        if ($accountObj.PasswordNeverExpires) {

            echo ("Password of account: " + $accountObj.Name + " is set to never expires!")

        } else {

            $passwordSetDate = $accountObj.PasswordLastSet

            if ($passwordSetDate -eq $null) {

                echo ("Password of account: " + $accountObj.Name + " has never been set!")

            }  else {

                $maxPasswordAgeTimeSpan = $null

                $dfl = (get-addomain).DomainMode

                if ($dfl -ge 3) { 

                    ## Greater than Windows2008 domain functional level

                    $accountFGPP = Get-ADUserResultantPasswordPolicy $accountObj

                    if ($accountFGPP -ne $null) {

                        $maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge

                    } else {

                        $maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

                    }

                } else {

                    $maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

                }

                if ($maxPasswordAgeTimeSpan -eq $null -or $maxPasswordAgeTimeSpan.TotalMilliseconds -eq 0) {

                    echo ("MaxPasswordAge is not set for the domain or is set to zero!")

                } else {

                    echo ("Password of account: " + $accountObj.Name + " expires on: " + ($passwordSetDate + $maxPasswordAgeTimeSpan))

                }

            }

        }

    }

}

}
Get-XADUserPasswordExpirationDate $username

Get-ADUser $username -Properties * | Select-Object DisplayName,LockedOut,LastLogonDate,kPMG-User-GOAccountType,kPMG-User-GOCompanyGroup,kPMG-User-GOFunction,kPMG-User-GOGrade,kPMG-User-GOManagementLevel,kPMG-User-GOMemberFirmGroup,kPMG-User-GPID,kPMG-User-GOMailDisclaimer,kPMG-User-GOMailSync

Если я запускаю скрипт в PowerShell, например. .\script.ps1 jsmith с 'jsmith' в качестве параметра работает, однако при использовании параметра C# он не принимает параметр и каждый раз выдает ошибку «Невозможно проверить аргумент для параметра 'Идентификация'».

Есть ли что-то, что я сделал неправильно в своем коде C #, из-за чего этот параметр не передается сценарию и принимает его в качестве входных данных?

Спасибо


person Nick Grabau    schedule 11.11.2015    source источник


Ответы (1)


Несколько мыслей:

  • Имя параметра в коде C# — имя пользователя.
  • Имя параметра в скрипте — accountIdentity.
  • Сообщение об ошибке ссылается на параметр Identity

Я думаю, что все 3 должны быть одинаковыми.

Если это не проблема, то возможный способ отладки проблемы состоит в том, чтобы превратить ваш код C# в сценарий PS. По крайней мере, мне было бы удобнее отлаживать сценарий PS, в котором я могу быстро изменять вещи (например, где вы создаете myCommand) и проверять их (с помощью get-member и select-object *), чем вы могли бы с C#.

Кроме того, для отладки вы также можете попробовать объединить все отдельные команды PS, чтобы закончить одним вызовом AddScript() вместо различных AddCommand() вместе с AddScript(). Я смутно припоминаю проблемы с их смешиванием, когда много лет назад писал похожий код.

person Χpẘ    schedule 17.11.2015