简体   繁体   English

将C#参数传递给Powershell脚本 - 无法验证参数'Identity'的参数

[英]Passing C# Parameter to Powershell Script - Cannot validate argument on parameter 'Identity'

I am trying to write a Windows Form App in C# that outputs AD Attributes for a specified user. 我试图在C#中编写一个Windows窗体应用程序,为指定用户输出AD属性。 The way I want it to work is that the user inputs a value (username) into a text box, which is passed as a parameter to the Powershell script and the output is displayed in the form. 我希望它工作的方式是用户将一个值(用户名)输入到文本框中,该文本框作为参数传递给Powershell脚本,输出显示在表单中。

My C# code for creating the parameter and invoking the script is as follows: 我用于创建参数和调用脚本的C#代码如下:

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();
    }

My PowerShell script is as follows: 我的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

If I run the script in PowerShell eg .\\script.ps1 jsmith with 'jsmith' as the parameter it works, however when using the C# parameter it does not accept the parameter and spits out a "Cannot validate argument on parameter 'Identity'" error every time. 如果我在PowerShell中运行脚本,例如。\\ script.ps1 jsmith,并使用'jsmith'作为参数,但是当使用C#参数时,它不接受参数并吐出“无法验证参数'Identity'的参数”每次都错误。

Is there something I have done wrong in my C# code that is causing this parameter to not pass to the script and accept it as input? 我的C#代码中是否有一些错误导致此参数未传递给脚本并将其作为输入接受?

Thanks 谢谢

A few thoughts: 一些想法:

  • The parameter name in the C# code is username C#代码中的参数名称是username
  • The parameter name in the script is accountIdentity 脚本中的参数名称为accountIdentity
  • The error message references parameter Identity 错误消息引用参数Identity

I would think all 3 should be the same. 我认为所有3应该是相同的。

If that's not the problem then a possible way to debug the problem is to turn your C# code into a PS script. 如果这不是问题,那么调试问题的一种可能方法是将您的C#代码转换为PS脚本。 For me, at least, I'd feel more comfortable debugging a PS script where I can rapidly change things (like where you build myCommand) and inspect them (with get-member and select-object *) than you might with C#. 对我来说,至少,我觉得调试一个PS脚本更舒服,我可以快速更改(比如你构建myCommand的地方)并检查它们(使用get-member和select-object *),而不是使用C#。

Also for debugging you might also try combining all the individual PS commands so that you end with a single invocation of AddScript(), instead of various AddCommand()s along with the AddScript(). 同样,对于调试,您可能还尝试组合所有单独的PS命令,以便以AddScript()的单个调用结束,而不是使用AddScript()而不是各种AddCommand()。 I vaguely remember problems with mixing the two when I wrote somewhat similar code many years ago. 我隐约记得多年前编写类似代码时混合二者的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM