PowerShell在Azure中没有要导出的数据时不会创建CSV。

huangapple go评论69阅读模式
英文:

Powershell does not create CSV if there is no data to export in Azure

问题

以下是翻译好的部分:

我正在尝试从Azure导出虚拟机数据如果订阅中有虚拟机则下面的脚本可以完美运行但是如果没有数据虚拟机),它不会创建.csv 文件我需要即使没有数据PowerShell也应该创建一个空白的 CSV 文件以下是我编写的脚本如果订阅中已创建虚拟机它可以正常运行

function create($path) {
    $exists = Test-Path -path $path
    Write-Host "尝试以下路径:$path,它" $(If ($exists) {"存在"} Else {"不存在!"}) 
    if (!($exists)) { New-Item $path -itemType Directory }
}

# 读取文件内容
$subs_file = "C:\Scrpting\Subscriptions\Subscriptions.xlsx"
$azSubs = Import-Excel $subs_file
$azSubs
$output_folder = "C:\audit-automation"
# 为输出数据创建文件夹
create("$output_folder")

# 遍历订阅
ForEach ( $sub in $azSubs ) {
    # 订阅
    $azsub = $sub.Subscription
    # 应用程序
    $app = $sub.Application
    $azsub
    $app
    # 创建保存应用程序数据的文件夹
    Set-AzContext -SubscriptionName $azsub
    # 获取虚拟机信息
    $vms = Get-AzVM
    $vmrg = Get-AzVM | Select-Object "ResourceGroupName"
    $nics = get-AzNetworkInterface | Where-Object { $_.VirtualMachine -NE $null }
    # 创建保存数据的文件夹
    create("$output_folder$app")
    ForEach ($nic in $nics) {
        $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        $vm = $vms | ? -Property Id -eq $nic.VirtualMachine.id
        $info.NICName = $nic.Name
        $info.VMName = $vm.Name
        $info.SubscriptionID = $azsub
        $info.ResourceGroupName = $vm.ResourceGroupName
        $info.PrivateIPAddress = $nic.IpConfigurations.PrivateIpAddress
        $PublicIPAddress =
        (Az vm list-ip-addresses --name $vm.Name --resource-group $vm.ResourceGroupName | ConvertFrom-Json).virtualMachine.network.publicIpAddresses.ipaddress
        $info.PublicIPAddress = if ($null -eq $PublicIPAddress ) { "Not Assigned" } else { $PublicIPAddress }
        $info.OS = $vm.StorageProfile.osDisk.osType
        $info.Status = ((Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1]).code
        $info | Export-Csv -Path $output_folder$app$app-vm_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append
    }
}

注意:上面的代码已被翻译成中文,其中的代码部分没有进行翻译。

英文:

I am trying to export VM data from Azure and below script is working perfect if subscription has VMs however it does create a .csv if there is no data (VMs) and I need that even if there is no data powershell should create a blank csv. Below is my script which is working fine if subscription has VMs created in it.

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:\Scrpting\Subscriptions\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
        # GET VM INFO
    $vms = Get-AzVM
    $vmrg = Get-AzVM | Select-Object "ResourceGroupName"
    $nics = get-AzNetworkInterface | Where-Object { $_.VirtualMachine -NE $null }
    # creating folder to save 
    # New-Item $output_folder$app\vm_info -itemType Directory
    create("$output_folder$app")
    ForEach ($nic in $nics) {
        $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        $vm = $vms | ? -Property Id -eq $nic.VirtualMachine.id
        $info.NICName = $nic.Name
        $info.VMName = $vm.Name
        $info.SubscriptionID = $azsub
        $info.ResourceGroupName = $vm.ResourceGroupName
        $info.PrivateIPAddress = $nic.IpConfigurations.PrivateIpAddress
        $PublicIPAddress =
        (Az vm list-ip-addresses --name $vm.Name --resource-group $vm.ResourceGroupName | ConvertFrom-Json).virtualMachine.network.publicIpAddresses.ipaddress
        $info.PublicIPAddress = if ($null -eq $PublicIPAddress ) { "Not Assigned" } else { $PublicIPAddress }
        $info.OS = $vm.StorageProfile.osDisk.osType
        $info.Status = ((Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1]).code
        $info | Export-Csv -Path $output_folder$app$app-vm_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append
    }}

答案1

得分: 0

在循环之外添加,因为 $vms 可能为空

if (!($vms)){
    $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
    $info | Export-Csv -Path $output_folder$app$app-vm_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append
}
英文:

add outside the loop, since $vms may be empty

if (!($vms)){
    $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
    $info | Export-Csv -Path $output_folder$app$app-vm_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append

}

答案2

得分: 0

你可以删除create函数,然后用这一行替换:$null = New-Item $output_folder -ItemType Directory -Force。在文件系统中,-Force参数会使命令返回现有文件夹的DirectoryInfo对象,或者创建一个新文件夹并返回该对象。(不要在注册表键上使用这个参数!)

接下来,如果你首先将要输出的内容捕获到CSV文件中,就很容易检查是否有输出,如果没有,就写入一个空的CSV文件(只有标题会在其中)。

类似这样:

# 读取文件内容
$subs_file = "C:\Scrpting\Subscriptions\Subscriptions.xlsx"
$azSubs    = Import-Excel $subs_file
$output_folder = "C:\audit-automation"
# 创建用于输出数据的文件夹
$null = New-Item $output_folder -ItemType Directory -Force

# 遍历订阅
foreach($sub in $azSubs) {
    # 订阅
    $azsub = $sub.Subscription
    # 应用程序
    $app = $sub.Application

    # 设置 Azure 配置
    Set-AzContext -SubscriptionName $azsub
    # 获取 VM 信息
    $vms  = Get-AzVM
    $vmrg = Get-AzVM | Select-Object "ResourceGroupName"
    $nics = Get-AzNetworkInterface | Where-Object { $null -ne $_.VirtualMachine }
    # 创建用于保存数据的文件夹
    $null = New-Item (Join-Path -Path $output_folder -ChildPath $app) -ItemType Directory -Force

    # 捕获 foreach 循环的输出
    $result = foreach ($nic in $nics) {
        $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        $vm   = $vms | ? -Property Id -eq $nic.VirtualMachine.id
        $info.NICName = $nic.Name
        $info.VMName  = $vm.Name
        $info.SubscriptionID    = $azsub
        $info.ResourceGroupName = $vm.ResourceGroupName
        $info.PrivateIPAddress  = $nic.IpConfigurations.PrivateIpAddress
        $PublicIPAddress = (Az vm list-ip-addresses --name $vm.Name --resource-group $vm.ResourceGroupName | 
                            ConvertFrom-Json).virtualMachine.network.publicIpAddresses.ipaddress
        $info.PublicIPAddress = if ($null -eq $PublicIPAddress ) { "Not Assigned" } else { $PublicIPAddress }
        $info.OS     = $vm.StorageProfile.osDisk.osType
        $info.Status = ((Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1]).code
        # 输出要在变量 $result 中收集的对象
        $info
    }
    # 检查一下现在是否有数据在变量 $result 中
    if (!@($result.Count)) {
        # 没有数据;创建一个只包含标题的空的 CSV 文件
        $result = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
    }
    $outFile = Join-Path -Path $output_folder -ChildPath ('{0}\{0}-vm_data{1:yyyy-MM-dd}.csv' -f $app, (Get-Date))
    $result | Export-Csv -Path $outFile -NoTypeInformation
}
英文:

You can remove the function create and replace that with just the one line $null = New-Item $output_folder -ItemType Directory -Force.
On file system, the -Force makes the cmdlet return either the DirectoryInfo object of an existing folder or create a new folder and return that.
(don't use this on registry keys!)

Next, if you capture the output you want in the CSV file first, it is easy enough to check if there is output or not and if not, write an empty csv file (only the headers will be in there)

Something like this:

# reading file contents 
$subs_file = "C:\Scrpting\Subscriptions\Subscriptions.xlsx"
$azSubs    = Import-Excel $subs_file
#$azSubs
$output_folder = "C:\audit-automation"
# creating folder for outputing data 
$null = New-Item $output_folder -ItemType Directory -Force

# iterating over subscriptions 
foreach($sub in $azSubs) {
    # sub
    $azsub = $sub.Subscription
    # app
    $app = $sub.Application
    $azsub
    $app

    # setting config for azure 
    Set-AzContext -SubscriptionName $azsub
    # GET VM INFO
    $vms  = Get-AzVM
    $vmrg = Get-AzVM | Select-Object "ResourceGroupName"
    $nics = Get-AzNetworkInterface | Where-Object { $null -ne $_.VirtualMachine }
    # creating folder to save 
    $null = New-Item (Join-Path -Path $output_folder -ChildPath $app) -ItemType Directory -Force

    # capture the output of the foreach loop
    $result = foreach ($nic in $nics) { 
        $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        $vm   = $vms | ? -Property Id -eq $nic.VirtualMachine.id
        $info.NICName = $nic.Name
        $info.VMName  = $vm.Name
        $info.SubscriptionID    = $azsub
        $info.ResourceGroupName = $vm.ResourceGroupName
        $info.PrivateIPAddress  = $nic.IpConfigurations.PrivateIpAddress
        $PublicIPAddress = (Az vm list-ip-addresses --name $vm.Name --resource-group $vm.ResourceGroupName | 
                            ConvertFrom-Json).virtualMachine.network.publicIpAddresses.ipaddress
        $info.PublicIPAddress = if ($null -eq $PublicIPAddress ) { "Not Assigned" } else { $PublicIPAddress }
        $info.OS     = $vm.StorageProfile.osDisk.osType
        $info.Status = ((Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1]).code
        # output the object to be collected in variable $result
        $info
    }
    # test if you actually have data now in the $result variable
    if (!@($result.Count)) {
        # no data; create an empty csv with just the headers
        $result = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
    }
    $outFile = Join-Path -Path $output_folder -ChildPath ('{0}\{0}-vm_data{1:yyyy-MM-dd}.csv' -f $app, (Get-Date))
    $result | Export-Csv -Path $outFile -NoTypeInformation
}

huangapple
  • 本文由 发表于 2023年2月14日 18:56:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75446835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定