azure 如果没有数据,则需要创建带标题的Powershell输出文件

xe55xuns  于 2023-02-16  发布在  Shell
关注(0)|答案(2)|浏览(84)

我已经创建了一个脚本,从Azure导出防火墙规则,它的工作完美,但我需要创建.csv与标题,即使没有数据。目前它正在创建一个空白文件。

``function create($path) {
    $exists = Test-Path -path $path
    Write-Host "tried the following path: $path, it" $(If ($exists) {"Exists"} Else {"Does not Exist!"}) 
    if (!($exists)) { New-Item $path -itemType Directory }
}

# reading file contents 
$subs_file =  "C:\script\Subscriptions.xlsx"
$azSubs = Import-Excel $subs_file
$azSubs
$output_folder = "C:\audit-automation"
# creating folder for outputing data 
create("$output_folder")
# New-Item $output_folder -itemType Directory

# iterating over subscriptions 
ForEach ( $sub in $azSubs ) {
    # sub
    $azsub = $sub.Subscription
    # app
    $app = $sub.Application
    $azsub
    $app
    # creating folder to save data for apps  
    # New-Item $output_folder\$app -itemType Directory
    # setting config for azure 
    Set-AzContext -SubscriptionName $azsub
        
    # FIREWALL RULES
    $azNsgs = Get-AzNetworkSecurityGroup
    # iterating over retrieved NSGs 
    $Output = ForEach ( $azNsg in $azNsgs ) {
        #Export custom rules
        Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $azNsg | `
            Select-Object @{label = 'NSG Name'; expression = { $azNsg.Name } }, `
        @{label = 'NSG Location'; expression = { $azNsg.Location } }, `
        @{label = 'Rule Name'; expression = { $_.Name } }, `
        @{label = 'Source'; expression = { $_.SourceAddressPrefix } }, `
        @{label = 'Source Application Security Group'; expression = { $_.SourceApplicationSecurityGroups.id.Split('/')[-1] } },
        @{label = 'Source Port Range'; expression = { $_.SourcePortRange } }, Access, Priority, Direction, `
        @{label = 'Destination'; expression = { $_.DestinationAddressPrefix } }, `
        @{label = 'Destination Application Security Group'; expression = { $_.DestinationApplicationSecurityGroups.id.Split('/')[-1] } }, `
        @{label = 'Destination Port Range'; expression = { $_.DestinationPortRange } }, `
        @{label = 'Resource Group Name'; expression = { $azNsg.ResourceGroupName } },
        @{label = 'Subscription Name'; expression = { $azSub } } 
    }
    # creating folder to save 
    # New-Item $output_folder\$app\firewall_rules -itemType Directory
    create("$output_folder\$app")
    $Output | Export-Csv -Path $output_folder\$app\$app-firewall_rules_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append`
piwo6bdm

piwo6bdm1#

测试$Output变量是否包含任何内容-如果没有,则创建一个与实际输出对象形状相同的“虚拟对象”,并将其与ConvertTo-Csv结合使用以生成标题:

# ...
create("$output_folder\$app")
$outputPath = "$output_folder\$app\$app-firewall_rules_data$((Get-Date).ToString("yyyy-MM-dd")).csv"

if($Output) {
    $Output | Export-Csv -Path $outputPath -Append -NoTypeInformation
}
elseif (-not(Test-Path $outputPath -PathType Leaf)) {
    # no output data, and the file doesn't already exist - create headers only
    $dummyObject = [pscustomobject]@{
        'NSG Name' = ''
        'NSG Location' = ''
        'Rule Name' = ''
        'Source' = ''
        'Source Application Security Group' = ''
        'Source Port Range' = ''
        'Destination' = ''
        'Destination Application Security Group' = ''
        'Destination Port Range' = ''
        'Resource Group Name' = ''
        'Subscription Name' = ''
    }

    # generate dummy CSV document, then discard the row representing the dummy object
    $header = $dummyObject |ConvertTo-Csv -NoTypeInformation |Select -SkipLast 1
    $header |Set-Content $outputPath

}
h4cxqtbf

h4cxqtbf2#

你遇到的问题是,如果$output中没有对象,那么Export-Csv就不能决定使用什么头文件,在这种情况下,你需要自己生成头文件文本文件......
这比@MathiasRJessen的答案稍微复杂一些,但它的优点是您只需要在代码中声明一次头文件,而不必在Select-Object参数和$dummyObject路径中保持同步...
首先,我们将属性定义从Select-Object移到一个变量中...

$csvColumns = @(
    @{label = 'NSG Name'; expression = { $azNsg.Name } },
    @{label = 'NSG Location'; expression = { $azNsg.Location } },
    @{label = 'Rule Name'; expression = { $_.Name } },
    @{label = 'Source'; expression = { $_.SourceAddressPrefix } },
    @{label = 'Source Application Security Group'; expression = { $_.SourceApplicationSecurityGroups.id.Split('/')[-1] } },
    @{label = 'Source Port Range'; expression = { $_.SourcePortRange } },
    "Access",
    "Priority",
    "Direction",
    @{label = 'Destination'; expression = { $_.DestinationAddressPrefix } },
    @{label = 'Destination Application Security Group'; expression = { $_.DestinationApplicationSecurityGroups.id.Split('/')[-1] } },
    @{label = 'Destination Port Range'; expression = { $_.DestinationPortRange } },
    @{label = 'Resource Group Name'; expression = { $azNsg.ResourceGroupName } },
    @{label = 'Subscription Name'; expression = { $azSub } }
);

那么Select-Object就变成了

Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $azNsg `
    | Select-Object $csvColumns

一旦我们让它工作了,我们就可以重用$csvColumns变量,用这个函数生成头文件:

function Get-CsvHeaderText
{
    param( $CsvColumns )

    # create a temporary hashtable to hold the header names in the keys
    $csvHeaders = [ordered] @{};

    # add the header names for each csv column - note that each item
    # can be a string (e.g. "Access") or a hashtable (e.g. "@{label = 'NSGLocation'; expression = { $azNsg.Location } }")
    foreach( $csvColumn in $CsvColumns )
    {
        if( $csvColumn -is [string] )
        {
            $csvHeaders.Add($csvColumn, [string]::Empty);
        }
        else
        {
            $csvHeaders.Add($csvColumn.Label, [string]::Empty);
        }
    }

    # now that we've got a fake object with the correct property names
    # we can convert it to csv and extract the header row(s). note - 
    # use "-SkipLast 1" to ignore the empty data row instead of
    # "-First 1" in case a header name has line breaks in it
    # (unlikely, but technically possible)
    $csvHeaderText = $headers | ConvertTo-csv | select-object -SkipLast 1;

    return $csvHeaderText;

}

示例用法:

$headerText = Get-CsvHeaderText -CsvColumns $csvColumns;

如果$output$null,则可以将其写入文件:

if( $null -eq $Output ) {
    $headerText = Get-CsvHeaderText -CsvColumns $csvColumns;
    $headerText | Set-Content "myfile.csv";
}
else
{
    $Output | Export-Csv -Path "myfile.csv" -Append -NoTypeInformation;
}

相关问题