Azure-Powershell Script error (ip address increment ) - azure

I hope you all doing well
can you please help me to solve this problem?
$ipnumber = 3
$RgName = "test"
$Location = "test"
for ($i = 0; $i -lt $ipnumber; $i++) {
$res1 = -join ((1..10) | ForEach-Object { get-random -minimum 97 -maximum 122 | ForEach-Object { [char]$_ } })
$res2 = -join ((1..10) | ForEach-Object { get-random -minimum 97 -maximum 122 | ForEach-Object { [char]$_ } })
$PublicIP = '$PublicIP'
$IpConfigName = '$IpConfigName'
$IpConfig = '$IpConfig'
$ip = '10.0.0.'
$x = 25
$PublicIP = $PublicIP + $i
$IpConfigName = $IpConfigName + $i
$IpConfig = $IpConfig + $i
$x = 25 + $i
$ip = $ip + $x
#####################################
# Create a public IP address
$PublicIP = New-AzPublicIpAddress `
-Name "$res1" `
-ResourceGroupName $RgName `
-Location $Location `
-AllocationMethod dynamic
#Create an IP configuration with a dynamic private IP address and assign the public IP address to it
$IpConfigName = "$res2"
$IpConfig = New-AzNetworkInterfaceIpConfig `
-Name $IpConfigName `
-Subnet $Subnet `
-PrivateIpAddress $ip `
-PublicIpAddress $PublicIP
}
$rand6 = -join ((1..10) | ForEach-Object { get-random -minimum 97 -maximum 122 | ForEach-Object { [char]$_ } })
$NIC = New-AzNetworkInterface `
-Name $rand6 `
-ResourceGroupName $RgName `
-Location $Location `
-NetworkSecurityGroupId $NSG.Id `
-IpConfiguration $IpConfig0, $IpConfig1, $IpConfig2
Error1 :
enter image description here
Error2 :
New-AzNetworkInterface: C:\Users\Marouane\Desktop\testpowershell\test2.ps1:95:22
Line |
95 | -IpConfiguration $IpConfig, $IpConfig0, $IpConfig1
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot bind parameter 'IpConfiguration'. Cannot convert the "$IpConfig1" value of type "System.String" to type
| "Microsoft.Azure.Commands.Network.Models.PSNetworkInterfaceIPConfiguration".
I want to increment the IP by 1
Ex : 10.0.0.25 next 10.0.0.26 next 10.0.0.27
but it says that you can't put in 'IpConfiguration' String ips
So what should i do ?
please help me!!
Thank you

I think Mainich you are trying do the array operation.
If I understand correctly, you are trying to create to create an array of the below variable :
$PublicIP = $PublicIP + $i
$IpConfigName = $IpConfigName + $i
$IpConfig = $IpConfig + $i
For instance,
IpConfig1,Ipconfig2,Ipconfig3 - and store the value accordingly.
Unfortunately, the implementation is slightly wrong
Please note : I have detailed the operation only for the $ipconfig variable. You can extend the same to other variables like $IpConfigName,$PublicIP
What Exactly is Happening
For all the iteration, $IpConfig gets updated & the variables you intended IpConfig1,Ipconfig2,Ipconfig3 are not created through the above logic.
You are initializing the variable ipConfig as a string
Overwriting the value of the variable ipconfig with the string value
$ipconfig1 (for the first iteration)
Overwriting the string value of the variable ipconfig with object.
AzNetworkInterfaceIpConfig
End of the iteration 1,
$ipconfig is with the value AzNetworkInterfaceIpConfig
ipconfig1 is non existant.
Suggestion :
The below creates an empty array with a fixed number - in your case 3 as $ipnumber = 3
$ipconfig = #() * $ipnumber
$ipconfig.append(New-AzNetworkInterfaceIpConfig `
-Name <>`
-Subnet<>`
-PrivateIpAddress <> `
-PublicIpAddress <>)
( or )
$ipconfig[0] = New-AzNetworkInterfaceIpConfig `
-Name <>`
-Subnet<>`
-PrivateIpAddress <> `
-PublicIpAddress <>
Now you can access the values through ipconfig[0], ipconfig[1],ipconfig[2]
Or you can pass the $ipconfig directly - as the parameter Ip configuration accepts the array value
-IpConfiguration <PSNetworkInterfaceIPConfiguration[]>
https://learn.microsoft.com/en-us/powershell/module/az.network/new-aznetworkinterface?view=azps-5.0.0
Suggestion 2:
if you would prefer creating the variable on the fly like ipconfig1,ipconfig2,ipconfig3, then you could do the below :
New-Variable -Name "Ipconfig$i" -Value <>
New-Variable -Name "Ipconfig$i" -Value <>
Get-Variable -Name "Ipconfig$i" -ValueOnly

Related

Automate NSG rule creation for NSGs within azure: Type error from Get-AzNetworkSecurityGroup

I am trying to write a script to automate creating NSG rules for our production NSGs. I am pretty sure I have something close to working but the issue I run into is that the Get-AZNetworkSecurityGroup command returns a string and so I cant feed it into the Add-AzNetworkSecurityRuleConfig command.
Import-Module Az.network
Connect-AzAccount
$tcpports = #(22,53,80,135,137,161,427,443,515,548,5060,5480,5985,5986,5989,9100,9443)
$udpports = #(53,161,427,515,548)
$solservers = #Server IP here
$file = Import-Csv C:\Users\temp\Downloads\AzureNSGs.csv
foreach ($NSG in $file){
$RGname=$NSG.'RESOURCE GROUP'
$nsgname=$NSG.NAME
$NSGObj = Get-AzNetworkSecurityGroup | Where-Object -Property Name -Like $RGname | Select-Object -Property Name
$name = "AllowSolarWinds"
if($NSGObj){
$name = $name + 1
$NSGObj | Add-AzNetworkSecurityRuleConfig -Name $name -NetworkSecurityGroup $NSGObj -Protocol Icmp -SourceAddressPrefix $solservers -DestinationPortRange "*" -Priority 555
$NSGObj | Set-AzNetworkSecurityGroup
}
}
Whenever I run this I get two kinds of returns. It either looks like it ran successfully with no errors but the rule is never created in azure. Or powershell spits out one of the following errors.
Add-AzNetworkSecurityRuleConfig : Cannot bind argument to parameter 'NetworkSecurityGroup' because it is null.
or
Add-AzNetworkSecurityRuleConfig : Cannot bind parameter 'NetworkSecurityGroup'. Cannot convert the value of type "System.String" to type
"Microsoft.Azure.Commands.Network.Models.PSNetworkSecurityGroup".
I tried to reproduce the same in my environment I got the same error like below:
To resolve the error, try to modify the code like below:
Connect-AzAccount
Import-Module Az.network
$tcpports = #(22,53,80,135,137,161,427,443,515,548,5060,5480,5985,5986,5989,9100,9443)
$udpports = #(53,161,427,515,548)
$solservers = "112.121.61.196"
$file = Import-Csv C:\Users\v-khanimran\Downloads\AzureNSGs.csv
foreach ($NSG in $file){
$RGname=$NSG.RESOURCEGROUPNAME
$nsgname=$NSG.NAME
$NSGObj =Get-AzNetworkSecurityGroup -Name $nsgname -ResourceGroupName $RGname
#Get-AzNetworkSecurityGroup | Where-Object {$_.Name -Like $nsgname} | Select-Object -Property Name
$name = "AllowSolarWinds"
if($NSGObj){
$name = $name + 1
$NSGObj | Add-AzNetworkSecurityRuleConfig -Name $name -Protocol Icmp -SourceAddressPrefix $solservers -DestinationPortRange "*" -SourcePortRange "*" -DestinationAddressPrefix "*" -Priority 555 -Access Allow -Direction Inbound
$NSGObj | Set-AzNetworkSecurityGroup
}
}
Output:
In the portal NSG rule got added successfully like below:

Powershell - Return Azure Blob Size by first split string value

So I am trying to list the contents on an Azure blog container size, I can get how much storage is being used as a whole. What I trying to do is break it down, by the first position of the filename.
And this is my sad attempt. Could someone point me in the right direction please?
$ResourceGroup = "RG"
$StorageAccountName = "SAN"
$ContainerName = "CN"
$storageAccount = Get-AzStorageAccount `
-ResourceGroupName $ResourceGroup `
-Name $StorageAccountName
$Context = $storageAccount.Context
$Blobs = Get-AzStorageBlob -Container $ContainerName -Context $Context
$length = 0
$Blobs | ForEach-Object {$length = $length + $_.Length }
#$Blobs.Name.Split("_",2)[0]
$Blobs | Select-Object Name, Length
$TotalSize = [math]::Round(($length / 1024 / 1024 / 1024 / 1024),2)
Write-Host "Total Size: $TotalSize Terabytes"
Current Output.
ABCD_History_20221127_110045 9306112
ABCD_History_20221204_110052 11010048
ABCD_History_20221211_110045 10616832
EFGH_20220327_110201 48562176
EFGH_20220403_110159 46596096
Total Size: 29.63 Terabytes
Desired Output
ABCD 30932992
EFGH 95158272
Total Size: 29.63 Terabytes
I have reproduced in my environment and got expected results as below and I followed Microsoft-Document:
$ResourceGroup = "XX"
$StorageAccountName = "rith"
$ContainerName = "rithwik"
$storageAccount = Get-AzStorageAccount `
-ResourceGroupName $ResourceGroup `
-Name $StorageAccountName
$Context = $storageAccount.Context
$Blobs = Get-AzStorageBlob -Container $ContainerName -Context $Context
$length = 0
$Blobs | ForEach-Object {$length = $length + $_.Length }
$Blobs | Select-Object Name, Length
After that used below code to get required Output:
foreach($emo in $blobs)
{
$BlobName=$Blobs.Name.Substring(0,3)
}
$Target = #()
foreach($emo in $BlobName)
{
$bn=$emo
$x=0
foreach($b in $blobs)
{
if ($b.Name -match $Bn)
{
$x=$x+$b.Length
}
}
$out = $bn + $x
$Target += $out
}
$Target | select -uniq
If you want 4 letters in output give 4 in substring command instead of 3.
If you space between name and length you use like below in place of $out = $bn + $x in for loop:
$out = $bn +" "+ $x

Optimize Powershell script for Azure NSG

I have a script for finding all inbound, allow rules in Azure NSG which source is any. It is doing his job but it takes just an enormous amount of time to iterate every rule in every available NSG in Azure.
Question is there is any way to optimize it, so it could work faster? Thanks!
function nsg {
# List of default rules which are skipped
$array =
'Default rules'
# Get all RG with NSG
$RGS = (Get-AzureRmResource -ODataQuery "`$filter=resourcetype eq 'Microsoft.Network/networkSecurityGroups'").ResourceGroupName | Sort-Object -Unique
foreach ($RG in $RGS) {
# List of all NSG names
$NSG_Names = (Get-AzureRmNetworkSecurityGroup -ResourceGroupName $RG).Name
# Get NSG rules
foreach ($NSG_Name in $NSG_Names){
$Rules = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig | Select-Object -ExpandProperty Name
# Check if rule is not default
foreach ($Rule in $Rules){
if ($array.contains($Rule)){
Write-Verbose "$Rule excluded because it is default!"
}
else {
Write-Verbose "$NSG_Name - $Rule"
#$DestinationAddressPrefix = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig -Name $Rule | Select-Object -ExpandProperty DestinationAddressPrefix
$DestinationPortRange = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig -Name $Rule | Select-Object -ExpandProperty DestinationPortRange
$SourceAddrPref = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig -Name $Rule | Select-Object -ExpandProperty SourceAddressPrefix
$SourcePortRange = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig -Name $Rule | Select-Object -ExpandProperty SourcePortRange
$Access = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig -Name $Rule | Select-Object -ExpandProperty Access
$Direction = Get-AzureRmNetworkSecurityGroup -Name $NSG_Name -ResourceGroupName $RG | Get-AzureRmNetworkSecurityRuleConfig -Name $Rule | Select-Object -ExpandProperty Direction
# Chek rule for every criterion, access type, etc.
if ($Direction -eq "Inbound" -and $SourceAddrPref -eq "*" -and $Access -eq "Allow"){ #-and $DestinationAddressPrefix -eq "*" -and $DestinationPortRange -eq "*") {
$message = "Warning! RG: $RG; NSG: $NSG_Name has SOURCE ANY Rule: $Rule to Destionation Port: $DestinationPortRange"
$message
}}}}}}
I don't think you need to iterate all that data. All those nested loops + sorting is whats causing the slowdown.
It seems to me that you just want to output all your NSGs with direction Inbound and access is Allow and source address prefix as *. If this is the case, you can do this:
$nsgs = Get-AzureRmNetworkSecurityGroup
foreach ($nsg in $nsgs.SecurityRules)
{
if ($nsg.Direction -eq "Inbound" -and $nsg.Access -eq "Allow" -and $nsg.SourceAddressPrefix -eq "*")
{
$nsg
}
}
Here we just iterate the security rules you have made from $nsgs.SecurityRules. The default ones are in $nsgs.DefaultSecurityRules. You can pipe to Get-Member to find these properties.

Create 2 publicIPs and assign to nics

I am trying to create 2 public ips and then assign one each to nics
for($i=1; $i -lt 3; $i++)
{
New-AzPublicIpAddress -Name "publicIP$i" -ResourceGroupName $resourceGroup.ResourceGroupName -Location $location -AllocationMethod Dynamic
New-AzNetworkInterface -Name "nic$i" -ResourceGroupName $resourcegroup.ResourceGroupName -Location $location -SubnetId $vnet.subnets[0].Id -PublicIpAddressId "publicIP$i.Id" -NetworkSecurityGroupId $nsg.Id
}
I want to assign the output of new-azPublicIpAddress to a variable and then use that variable's id to assign to -pulicIpAddressId.
like this $pip$i = New-AzPublicIpAddress -Name "publicIP$i" -ResourceGroupName $resourceGroup.ResourceGroupName -Location $location -AllocationMethod Dynamic but this does not work
You cannot set a variable with a '$' inside it.
The following is a correct sample.
$pip = New-AzPublicIpAddress -Name "publicIP$i" -ResourceGroupName $resourceGroup.ResourceGroupName -Location $location -AllocationMethod Dynamic
Considering your requirement, I suggest you use an array:
$pipArr = New-Object 'Object[]' 2;
$nicArr = New-Object 'Object[]' 2;
for($i=0; $i -lt 2; $i++)
{
$pipArr[$i] = New-AzPublicIpAddress -Name "publicIP$i" -ResourceGroupName $resourceGroup.ResourceGroupName -Location $location -AllocationMethod Dynamic
$nicArr[$i] = New-AzNetworkInterface -Name "nic$i" -ResourceGroupName $resourcegroup.ResourceGroupName -Location $location -SubnetId $vnet.subnets[0].Id -PublicIpAddressId $pipArr[$i].Id -NetworkSecurityGroupId $nsg.Id
}
In this way, you can get your first public IP with "$pipArr[0]". As it is an array, you can use index with it.
As Jack requested, here's another way of doing the same is the following:
Set-Variable "pip$i" -Value (New-AzPublicIpAddress -Name "publicIP$i" -ResourceGroupName $resourceGroup.ResourceGroupName -Location $location -AllocationMethod Dynamic)
then you can use Get-Variable to get data from the variable:
Get-Variable "pip$i" | Select -ExpandProperty Value
If you just want to have $ inside the variable you can do this:
${pip$i} = something
this will instanciate new variable with the name pip$i, and you could retrieve it similarly as well:
Do-something -Input ${pip$i}

Run Powershell Cmdlet with various number of parameters

I'm scripting some configuration of Azure Analysis Service, and more specifically the firewall. The cmdlet
New-AzAnalysisServicesFirewallConfig -FirewallRule
takes in the rules created as a parameter; $rule1 as an example.
I want the script to be able to take a varying number of parameters to that command. Instead of having to hardcode it to X number of rules like in the example with 6 rules.
I tried to create an Array and a Hashtable containing the X number of parameters, but it's unable to convert them.
$FirewallRules | ForEach-Object {
$ruleNumberVar = "rule" + "$ruleNumberIndex"
if (!($_.FirewallRuleName -match "$ExistingFirewallRuleName")) {
$start = $_.RangeStart
$end = $_.RangeEnd
$tempRule = New-AzAnalysisServicesFirewallRule `
-FirewallRuleName $_.FirewallRuleName `
-RangeStart $start `
-RangeEnd $end
Set-Variable -Name "$ruleNumberVar" -Value $tempRule
$ruleNumberIndex = $ruleNumberIndex + 1
}
$conf = New-AzAnalysisServicesFirewallConfig -FirewallRule $rule1,$rule2,$rule3,$rule4,$rule5,$rule6
Getting this error:
New-AzAnalysisServicesFirewallConfig : Cannot bind parameter 'FirewallRule'. Cannot convert the "System.Collections.Hashtable" value of type "System.Collectio
ns.Hashtable" to type "Microsoft.Azure.Commands.AnalysisServices.Models.PsAzure
AnalysisServicesFirewallRule".
This is untested and therefore theoretical, but this should fix that error if the type can be casted.
$Rules = #() -as [System.Collections.Generic.List[Microsoft.Azure.Commands.AnalysisServices.Models.PsAzureAnalysisServicesFirewallRule]]
$FirewallRules | ForEach-Object {
$ruleNumberVar = "rule" + "$ruleNumberIndex"
if (!($_.FirewallRuleName -match "$ExistingFirewallRuleName")) {
$start = $_.RangeStart
$end = $_.RangeEnd
$tempRule = New-AzAnalysisServicesFirewallRule `
-FirewallRuleName $_.FirewallRuleName `
-RangeStart $start `
-RangeEnd $end
Set-Variable -Name $ruleNumberVar -Value $tempRule
$Rules.Add((Get-Variable $ruleNumberVar -ValueOnly))
$ruleNumberIndex = $ruleNumberIndex + 1
}
}
$conf = New-AzAnalysisServicesFirewallConfig -FirewallRule $Rules

Resources