搜索脚本文件以获取参数

时间:2014-05-07 10:20:41

标签: c# regex powershell

我在C#中寻找一种方法来搜索PowerShell脚本文件的参数。

我的PowerShell脚本顶部包含以下内容:

 [CmdletBinding()]  
    param(
    [Parameter(Position=1, Mandatory=$true)] [string]$Domain,
    [Parameter(Position=2, Mandatory=$true)] [string]$SIPDomain,
    [Parameter(Position=3, Mandatory=$true)] [string]$RegistrarPool,
    [Parameter(Position=4, Mandatory=$true)] [string]$ExchangeServer,
    [Parameter(Position=5, Mandatory=$true)] [string]$OU,  
    [Parameter(Position=6, Mandatory=$false)] [string]$SleepTime="10",
    [Parameter(Position=7, Mandatory=$false)] [bool]$CreateAA=$true,
    [Parameter(Position=8, Mandatory=$false)] [bool]$CreateSA=$true
    ) 

对于每个参数,我想存储它的位置,无论是强制,类型,变量名称还是默认值(如果有)。我也希望除变量之外的所有变量都是强制性的,因为某些脚本可能具有非常基本的参数,例如

param($name, $test)

对于上面的示例,我想要一个看起来像这样的对象:

位置强制类型变量DefaultValue(' ='之后的位)

1 $true String $Domain
2 $true String $SIPDomain
3 $true String $RegistrarPool
4 $true String $ExchangeServer
5 $true String $OU
6 $false String $SleepTime 10
7 $false bool $CreateAA $true
8 $false bool $CreateSA $true

我花了几个小时试图使用正则表达式进行正确的拆分,但我认为这种模式对我来说有点过于复杂。

真的很感激一些帮助。

谢谢, 安德鲁

2 个答案:

答案 0 :(得分:0)

这仅适用于V3:

(@'
[CmdletBinding()]  
    param(
    [Parameter(Position=1, Mandatory=$true)] [string]$Domain,
    [Parameter(Position=2, Mandatory=$true)] [string]$SIPDomain,
    [Parameter(Position=3, Mandatory=$true)] [string]$RegistrarPool,
    [Parameter(Position=4, Mandatory=$true)] [string]$ExchangeServer,
    [Parameter(Position=5, Mandatory=$true)] [string]$OU,  
    [Parameter(Position=6, Mandatory=$false)] [string]$SleepTime="10",
    [Parameter(Position=7, Mandatory=$false)] [bool]$CreateAA=$true,
    [Parameter(Position=8, Mandatory=$false)] [bool]$CreateSA=$true
    )
'@).split("`n") |
foreach {$_.trim()} | sc testparams.ps1

$AST = [System.Management.Automation.Language.Parser]::
ParseFile('c:\testfiles\testparams.ps1',[ref]$null,[ref]$null)

$AST.ParamBlock.Parameters | 
 foreach {
   $IsMandatory = $_.Extent.Text -match 'Mandatory=\$true'
   $Position = $_.Extent.Text -replace '.+Position=(\d+).+','$1'
   New-Object PSObject -Property @{
                                    Name = $_.Name
                                    Type = $_.StaticType
                                    Position = $Position
                                    Mandatory = $IsMandatory
                                    }
        } | Select Name,Type,Position,Mandatory | ft -auto

Name            Type           Position Mandatory
----            ----           -------- ---------
$Domain         System.String  1             True
$SIPDomain      System.String  2             True
$RegistrarPool  System.String  3             True
$ExchangeServer System.String  4             True
$OU             System.String  5             True
$SleepTime      System.String  6            False
$CreateAA       System.Boolean 7            False
$CreateSA       System.Boolean 8            False

答案 1 :(得分:0)

您可以使用以下代码获取指定的相同输出:

var matches = Regex.Matches(script, @"\s*\[Parameter\(.*?\)\].*?,");

foreach (var match in matches)
{
    string result = Regex.Replace(match.ToString().Trim(), @".*Position=(.*?),\s*Mandatory=(.*?)\).*?\[(.*?)\](.*?)(=""(.*?)""|\s*),", "$1 $2 $3 $4 $6");
    Console.WriteLine(result);
}

这首先匹配包含Parameter模式的行。然后,对于每一行,它提取所需的输出。

<强>更新 要将数据转换为变量,请在foreach循环中使用以下行:

 var datamatch = Regex.Match(match.ToString().Trim(), @".*Position=(.*?),\s*Mandatory=(.*?)\).*?\[(.*?)\](.*?)(=""(.*?)""|\s*),");

然后使用datamatch.Groups[1]datamatch.Groups[2]等来获取字符串,之后将Parse字符串添加到您需要的类型中。例如,对于整数,请使用int.Parse