如何向命令添加未知数量的变量

时间:2018-04-16 18:17:19

标签: powershell

我有一个我试图修改的脚本,它通过powershell使用Invoke-RestMethod将对象添加到防火墙

当前脚本具有以下代码;

#Import CSV and set variables
$csv = import-csv C:\Powershell\groups.csv

# RESTful API Call
$csv | ForEach-Object {
            $Name = $_.name
            $Member1 =$_.member1
            $Member2 =$_.member2
            Invoke-RestMethod -Uri https://172.16.16.16:4444/webconsole/APIController?reqxml=<Request><Login><Username>admin</Username><Password>password</Password></Login><Set%20operation=%27add%27><IPHostGroup><Name>$Name</Name><IPFamily>IPv4</IPFamily><HostList><Host>$Member1</Host><Host>$Member2</Host></IPHostGroup></Set></Request>
} 

我想通过groups.csv导入主机组,其中(在我的测试中)有3列,如下所示;

Name,Member1,Member2
TestGroup,TestHost1,TestHost2
TestGroup2,TestHost3,TestHost4

我的问题是,在真实数据中,每组中有不同数量的主机,有些主机有数百台。我不确定如何在不为每个可能的成员定义变量的情况下将这些内容输入命令。即使这样,我说我创建了$ Member(s)到200(温和,我不是真正的编码器!)然后在Invoke-Restmethod命令中逐个手动导入它们(可能也是如此)在那一点上手工完成!)我不确定在组中只有少数主机的情况下命令会处理空白输入。

(换句话说,如果我的csv有以下条目;)

Name,Member1,Member2,Member3,Member4
TestGroup,TestHost1,TestHost2,TestHost3,TestHost4
TestGroup2,TestHost5,TestHost6
TestGroup3,TestHost7

我做了;

# RESTful API Call
$csv | ForEach-Object {
            $Name = $_.name
            $Member1 =$_.member1
            $Member2 =$_.member2
            $Member3 =$_.member3
            $Member4 =$_.member4

第三组的休息呼叫将最终以“

>的形式运行
Invoke-RestMethod -Uri https://172.16.16.16:4444/webconsole/APIController?reqxml=<Request><Login><Username>admin</Username><Password>password</Password></Login><Set%20operation=%27add%27><IPHostGroup><Name>TestGroup3</Name><IPFamily>IPv4</IPFamily><HostList><Host>TestHost7</Host><Host></Host><Host></Host><Host></Host></IPHostGroup></Set></Request>

有人能指出我更好的方法吗?

1 个答案:

答案 0 :(得分:0)

您可以使用.PSObject.Properties.Name

获取所有会员名称

示例:

$Csv = Import-Csv -Path 'C:\Powershell\groups.csv'

# Request XML template
$RequestTpl = @'
<Request>
<Login>
<Username>admin</Username>
<Password>password</Password>
</Login>
<Set%20operation=%27add%27>
<IPHostGroup>
<Name>{0}</Name>
<IPFamily>IPv4</IPFamily>
<HostList>
{1}
</HostList>
</IPHostGroup>
</Set>
</Request>
'@

# Host list XML template
$RequestHostListTpl = '<Host>{0}</Host>'

$Csv | ForEach-Object {
    <#
        Get names of all the properties in the current object
        Leave only those that don't match '^Name$' regex.
        -match, when operates on collections, returns matched items
        You can use

        $_.PSObject.Properties.Name | Where-Object {$_ -ne 'Name'}

        but it's a bit slower.
    #>
    $Members = @($_.PSObject.Properties.Name) -notmatch '^Name$'

    # Build list of hosts
    $RequestHostList = foreach ($item in $Members) {
        # Only add item if it's not empty
        if ($_.$item) {
            $RequestHostListTpl -f $_.$item
        }
    }

    # Build request XML
    $Request = $RequestTpl -f $_.Name, -join $RequestHostList

    # Remove newlines to make it one long string
    $Request = $Request -replace '\r|\n'

    # Show resulting url
    "Invoke-RestMethod -Uri https://172.16.16.16:4444/webconsole/APIController?reqxml=$Request"

    # Uncomment to actually invoke API call
    #Invoke-RestMethod -Uri "https://172.16.16.16:4444/webconsole/APIController?reqxml=$Request"
}