Powershell jobs and Set-AzureRmRouteTable - azure

I keep getting this error when I use this cmdlet in my script block
Cannot parse the request.
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : '2410b534-3ab9-4c82-b0fa-233e5a36e795'
+ CategoryInfo : CloseError: (:) [Set-AzureRmRouteTable], NetworkCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Network.SetAzureRouteTableCommand
+ PSComputerName : localhost
Makes no sense to me. Everytime I search this error, it references Network related cmdlets.
$addConfigBlock = {
Param(
$udr,
$routeTableName,
$routeTableRG
)
$routeTable = Get-AzureRmRouteTable -ResourceGroupName $routeTableRG -Name $routeTableName
try{
Add-AzureRmRouteConfig -RouteTable $routeTable `
-Name $udr.Name `
-AddressPrefix $udr.properties.addressPrefix `
-NextHopType $udr.properties.nextHopType | `
Set-AzureRmRouteTable | Out-Null
}
catch {
$ErrorMessage = $_.Exception.Message
Write-Output "$ErrorMessage"
}
}
foreach( $routeTable in $routeTablesToUpdate){
Write-Output "Updating routes in route table : $($routeTable.Name) ..."
ForEach($udr in $udrGov){
Start-Job -ScriptBlock $addConfigBlock -ArgumentList $udr, $routeTable.Name, $routeTable.ResourceGroupName
}
}
Some of the new configurations are added to my route table, but some error out with that error.. Hm..
New error -
A retryable error occurred.
StatusCode: 429
ReasonPhrase:
OperationID : '927995e6-da07-4f99-bbf3-6dd59e7c3183'
+ CategoryInfo : CloseError: (:) [Set-AzureRmRouteTable], NetworkCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Network.SetAzureRouteTableCommand
+ PSComputerName : localhost

I have reproduced your issue via an existing route name, before I run the command, I have a route called joyroute1 in the route table.
My test command:
$routeTable = Get-AzureRmRouteTable -ResourceGroupName joywebapp -Name joyudr
Add-AzureRmRouteConfig -RouteTable $routeTable `
-Name joyroute1 `
-AddressPrefix 10.1.0.0/18 `
-NextHopType VirtualNetworkGateway | `
Set-AzureRmRouteTable -Debug
Debug result:
So I think that your script uses conflict names of the routes, when it using some different names, it works, this explains why some of them work, you could check it.

Related

Set-AzRecoveryServicesAsrVaultContext : Operation failed

Below script works for one recovery vault but fails for another.
Script
$Sub = Get-AzSubscription -SubscriptionName ''
$context = $Sub | Set-AzContext
$rv = Get-AzRecoveryServicesVault -ResourceGroupName '' -Name ''
Set-AzRecoveryServicesAsrVaultContext -Vault $rv -defaultprofile $context
Error
Set-AzRecoveryServicesAsrVaultContext : Operation failed.
Download vault credential file using cmdlet Get-AzRecoveryServicesVaultSettingsFile and Import-AzRecoveryServicesAsrVaultSettingsFile
At line:1 char:1
+ Set-AzRecoveryServicesAsrVaultContext -Vault $rv -defaultprofile $con
+ CategoryInfo : CloseError: (:) [Set-AzRecoveryServicesAsrVaultContext], Exception
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.RecoveryServices.SiteRecover
Hi the issue was related to vnet configuration. now it is resolved.
error was was coming as data was not passing from one vnet to another.

Failed when running powershell code in azure automation

I set an azure policy adding two tags, which are CreatedTime and Type.
The value of CreatedTime is utcNow(), which default format is 'yyyy-MM-ddTHH:mm:ss.fffffffZ'.
My goal is to delete all resources whose Type is private and created time is longer than 2 days by running powershell code in azure automation.
I have done it in power shell locally, but when I run the code in automation, it failed. I will post the code and the error page below.
Anybody can tell me what's wrong with my code? Or I miss something?
This is my code in Azure Automation:
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint
$servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$AllRes = (get-AzureRMResource).ResourceId
$TimeOutDays=2
foreach ($Res in $AllRes){
$Resource = Get-AzureRMResource -ResourceId $Res
$Tags=$Resource.Tags
$TypeInTags=$Tags['Type']
$CreatedTimeInTags=$Tags['CreatedTime']
try{
$CreatedTime=[Datetime]::ParseExact($CreatedTimeInTags, 'MM/dd/yyyy HH:mm:ss', $null)
}
catch{
$CreatedTime=[Datetime]::ParseExact($CreatedTimeInTags, 'yyyy-MM-ddTHH:mm:ss.fffffffZ', $null)
}
finally
{
$CreatedTime
}
$daypan=((get-date)-$CreatedTime).Days
if($TypeInTags -eq 'private')
{
if($daypan -gt $TimeOutDays)
{
$daypan
Remove-AzureRMResource -ResourceId $Res -Force
}
}
}
This is the error page:
Suspended
The runbook job was attempted 3 times, but it failed each time. Common reasons that runbook jobs fail can be found here: https://learn.microsoft.com/en-us/azure/automation/automation-troubleshooting-automation-errors
A piece of error message:
Get-AzureRMResource : ResourceNotFound : The Resource
'microsoft.alertsmanagement/smartDetectorAlertRules/Failure+Anomalies+-+arrowbottest2-config' under resource group
'arrowbot2' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix
At line:28 char:17
+ $Resource = Get-AzureRMResource -ResourceId $Res
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzureRmResource], ErrorResponseMessageException
+ FullyQualifiedErrorId :
ResourceNotFound,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.GetAzureResourceCmdlet
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At line:34 char:5
+ $CreatedTime=[Datetime]::ParseExact($Tags['CreatedTime'], 'yyyy-M ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException
Cannot find an overload for "op_Subtraction" and the argument count: "2".
At line:35 char:5
+ $daypan=((get-date)-$CreatedTime).Days
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
Cannot find an overload for "op_Subtraction" and the argument count: "2".
At line:35 char:5
+ $daypan=((get-date)-$CreatedTime).Days
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At line:34 char:5
+ $CreatedTime=[Datetime]::ParseExact($Tags['CreatedTime'], 'yyyy-M ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException
For the type of $Tags['CreatedTime'], I did this for a test: $Tags['CreatedTime'].GetType().FullName.
Since you say The value of CreatedTime is utcNow(), then that value is already a DateTime object and you should not treat it as string. (you think it is a string, because when you write it out to console, it will show its ToString() representation)
Simply do
$CreatedTime=$Tags['CreatedTime']
You can test this with a write-host $Tags['CreatedTime'].GetType().FullName
There are two things wrong.
1.Didn't specify the resource I need.
Detailes:
That's the reason for the error message: Can not index to a null array. I traverse the entire resource in my subscription, but the
resources created before I set the policy do not have a Tag named
"CreatedTime" or "Type", so when I run $Tags=$Resource.Tags, it
said Can not index to a null array.
My solution:
Do $AllRes = (get-AzResource -TagName "CreatedTime").ResourceId other than $AllRes = (get-AzureRMResource).ResourceId.
I found that AzureRM module don't
recognize -TagName as a variable, so I import the Az module and
change every AzureRM module to Az module.
2.Confused with utcNow().
Details:
As I said, with utcNow() function I get a DateTime object with default
format 'yyyy-MM-ddTHH:mm:ss.fffffffZ', after testing a lot,
I found some special resources like application insight' tag value is
not formated with 'yyyy-MM-ddTHH:mm:ss.fffffffZ', and when I call
it, it comes to a string.
My solution:
So when I use it comparing to get-date, I
need to do two things:
(1)Change the string to DateTime object;
(2)Use try-catch to meet two kinds of formats.

Set-AzVMCustomScriptExtension in catch?

Attempting to add an extension when not detected but keep failing to find the secret sauce to get this to work. Mind you I am a BASH guy and this is a first foray into PowerShell..
#requires -version 2
# Required parameter $subscription: name of the subscription to enable Custom Script Extensions in
param (
# NOTE: See below for reason...
# [Parameter(Mandatory = $true)] [String] $subscription
# NOTE: Prompting is great for using the script interactively, but if this will also be executed
# from a build server or ...
# NOTE: Once the parameter is marked as mandatory PowerShell it will prompt for value. That said,
# if you remove the mandatory attribute then you can set a default value as a T_THROW ...
# NOTE: This _does_ contain shortcomings if this will be used as a pipeline param ...
# https://stackoverflow.com/questions/33600279/is-it-possible-to-force-powershell-script-to-throw-if-a-required-pipeline-para
[Parameter()]
[ValidateNotNullOrEmpty()]
[String]$SubscriptionName=$(Throw "`SubscriptionName` is mandatory, please provide a value...")
)
# Connect to the current Azure account
Write-Output "Pulling Azure account credentials..."
Start-Process "https://microsoft.com/devicelogin" # steals focus...
# Login to Azure account
Connect-AzAccount
# Set the active subscription
$null = Get-AzSubscription -SubscriptionName "$SubscriptionName" |Set-AzContext
# TODO: error handling
$vms = Get-AzVM
$cseName = "VulnerabilityManagementTools"
ForEach ($vm in $vms) {
try {
$cseStatus = Get-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroupName `
-VMName $vm.Name `
-Name $cseName `
-Status
}
catch {
Write-Output "Enabling Custom Script Extension for $vm."
Set-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroup `
-Location $vm.Location `
-VMName $vm.Name `
-Name $cseName `
-TypeHandlerVersion "1.1" `
-StorageAccountName "VulnerabilityManagementTools" `
-FileName "VulnerabilityManagementInstaller.ps1" `
-ContainerName "VulnerabilityManagementTools"
}
}
End up err'ing out with
PS /.../automation-scripts> ./EnableCustomScriptExtension.ps1 SubscriptionName
Pulling Azure account credentials...
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXX to authenticate.
Account SubscriptionName TenantId Environment
------- ---------------- -------- -----------
XXXX#analytics.com SubName XXXXXX-XXXX AzureCloud
Get-AzVMCustomScriptExtension : The Resource 'Microsoft.Compute/virtualMachines/XXXX/extensions/VulnerabilityManagementTools' under resource group '{NAME}' was not found.
ErrorCode: ResourceNotFound
ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/XXXX/extensions/VulnerabilityManagementTools' under resource group '{NAME}' was not found.
ErrorTarget:
StatusCode: 404
ReasonPhrase: Not Found
At /.../automation-scripts/EnableCustomScriptExtension.ps1:59 char:18
+ $cseStatus = Get-AzVMCustomScriptExtension `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzVMCustomScriptExtension], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.GetAzureVMCustomScriptExtensionCommand
Get-AzVMCustomScriptExtension : The Resource 'Microsoft.Compute/virtualMachines/XXXXX/extensions/VulnerabilityManagementTools' under resource group '{RESOURCE_GROUPNAME}' was not found.
ErrorCode: ResourceNotFound
ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/XXXX/extensions/VulnerabilityManagementTools' under resource group '{RESOURCE_GROUPNAME}' was not found.
ErrorTarget:
StatusCode: 404
ReasonPhrase: Not Found
At /.../automation-scripts/EnableCustomScriptExtension.ps1:59 char:18
+ $cseStatus = Get-AzVMCustomScriptExtension `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzVMCustomScriptExtension], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.GetAzureVMCustomScriptExtensionCommand
Get-AzVMCustomScriptExtension : The Resource 'Microsoft.Compute/virtualMachines/{VMName}/extensions/VulnerabilityManagementTools' under resource group '{RESOURCEX_GROUPNAME}' was not found.
ErrorCode: ResourceNotFound
ErrorMessage: The Resource 'Microsoft.Compute/virtualMachines/{VMName}/extensions/VulnerabilityManagementTools' under resource group '{RESOURCEX_GROUPNAME}' was not found.
ErrorTarget:
StatusCode: 404
ReasonPhrase: Not Found
At /.../automation-scripts/EnableCustomScriptExtension.ps1:59 char:18
+ $cseStatus = Get-AzVMCustomScriptExtension `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzVMCustomScriptExtension], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.GetAzureVMCustomScriptExtensionCommand`
In your case, you just need to use the if(){}else{} statement, try the script as below instead of the ForEach part of yours, it works fine on my side.
ForEach ($vm in $vms) {
$cseStatus = Get-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroupName `
-VMName $vm.Name `
-Name $cseName `
-Status `
-ErrorAction SilentlyContinue
if ($cseStatus){
Write-Host "The extension has been set for" $vm.Name
}else{
Write-Host "Enabling Custom Script Extension for" $vm.Name
Set-AzVMCustomScriptExtension `
-ResourceGroupName $vm.ResourceGroup `
-Location $vm.Location `
-VMName $vm.Name `
-Name $cseName `
-TypeHandlerVersion "1.1" `
-StorageAccountName "VulnerabilityManagementTools" `
-FileName "VulnerabilityManagementInstaller.ps1" `
-ContainerName "VulnerabilityManagementTools"
}
}
Test result:
You'll need to create an Azure AD Service Principal using password authentication and use the credentials of this to pass to the Connect-AzAccount cmdlet as follows:
$credentials = Get-Credential
Connect-AzAccount -ServicePrincipal -Credentials $credentials
The service account will need to have the necessary permissions to use the Set-AzVMCustomScriptExtensions cmdlet.
More information on creating the service account here:
https://learn.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps?view=azps-2.8.0

Enable/Disable availability tests in Azure on Schedule

I'm wondering if there is an easy way to run scheduled automation commands in Azure.
I managed to write Enable/Disable command for availability tests both in
Azure CLI:
az resource update --set properties.enabled=true --name 'someName' --resource-type 'Microsoft.Insights/webtests' --resource-group 'soemResourceGroup'
and
Powershell:
#Get All webTests
$resourceGroupnames = "someGroupName1", "someGroupName2";
$enableTests = "True";
ForEach ($resourceGroupname in $resourceGroupnames) {
$resourceGroupname
$allAvailabilityTestsIds = Get-AzureRmResource -ResourceGroupName $resourceGroupname `
| Where-Object -Property ResourceType -EQ "microsoft.insights/webtests" `
| Select-Object -ExpandProperty ResourceId;
ForEach ($availabilityTestId in $allAvailabilityTestsIds) {
$availabilityTest = Get-AzureRmResource -ResourceId $availabilityTestId;
$availabilityTest.Properties.Enabled = $enableTests;
$availabilityTest | Set-AzureRmResource -Force;
}
}
problem is that I'm not sure to run them outside of Comamnd line and on schedule. I've read that I could use Automation account to use powershell scripts but that seems a nightmare since I got tons of issues with authentication (not sure why).
Is that an only way ?
EDIT:
I post the errror I was/am getting below.
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Set-AzureRmResource : Cannot validate argument on parameter 'Sku'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:37 char:29
+ $availabilityTest | Set-AzureRmResource -Force;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Azure...dels.PSResource:PSObject) [Set-AzureRmResource],
ParameterBindingValidationException
+ FullyQualifiedErrorId :
ParameterArgumentValidationError,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetAzureResourceCmdlet
Regards.
You could follow the steps as below to use the azure runbook in automation to do that.
1.Navigate to your automation account -> Runbooks -> Create a runbook -> create a Powershell runbook.
2.In the runbook, add the script to login, your complete script should be like below. (Before running the runbook, make sure you have imported the AzureRM.Resources and AzureRM.Profile powershell module in your automation account -> Modules, if not, in the Modules -> Browse Gallery, search for the modules and import them.)
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
#Get All webTests
$resourceGroupnames = "someGroupName1", "someGroupName2";
$enableTests = "True";
ForEach ($resourceGroupname in $resourceGroupnames) {
$resourceGroupname
$allAvailabilityTestsIds = Get-AzureRmResource -ResourceGroupName $resourceGroupname `
| Where-Object -Property ResourceType -EQ "microsoft.insights/webtests" `
| Select-Object -ExpandProperty ResourceId;
ForEach ($availabilityTestId in $allAvailabilityTestsIds) {
$availabilityTest = Get-AzureRmResource -ResourceId $availabilityTestId;
$availabilityTest.Properties.Enabled = $enableTests;
$availabilityTest | Set-AzureRmResource -Force;
}
}
3.After running the script successfully, follow this link Scheduling a runbook in Azure Automation to add a schedule to your runbook.

Set-AzureRmResourceGroup : 'resourceGroupName' does not match expected pattern '^[-\w\._\(\)]+$'

Running this below and can't seem to get the collection correct to pass into the ForEach loop, even though it returns the names I want.
$RGInfo returns as expected. But when I pass it into the loop to Set-AzureRmResourceGroup, it errors as below
PS H:\> $rginfo
ResourceGroupName
-----------------
rg-crp-d365-bp-n
rg-crp-d365-dev1-n
rg-crp-d365-dev2-n
rg-crp-d365-upgrad-n
$RGInfo = Get-AzureRmResourceGroup | Where-Object {$_.ResourceGroupName -like "RG-CRP-D365*" } | Select-Object ResourceGroupName
ForEach ($RGName in $RGInfo) {
If ($RGName.Tags -eq $null) {
Set-AzureRmResourceGroup -ResourceGroupName $RGName -Tag #{BUSINESS_UNIT="CRP"; COST_CENTER="6435" }
}
}
Know why I keep getting the below? There are four RG's so the ForEach loop is functional.
Set-AzureRmResourceGroup : 'resourceGroupName' does not match expected
pattern '^[-\w._()]+$'. At line:7 char:2
+ Set-AzureRmResourceGroup -ResourceGroupName $RGName -Tag #{BUSINESS_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzureRmResourceGroup], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetA
zureResourceGroupCmdlet Set-AzureRmResourceGroup :
'resourceGroupName' does not match expected pattern '^[-\w._()]+$'.
At line:7 char:2
+ Set-AzureRmResourceGroup -ResourceGroupName $RGName -Tag #{BUSINESS_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzureRmResourceGroup], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetA
zureResourceGroupCmdlet Set-AzureRmResourceGroup :
'resourceGroupName' does not match expected pattern '^[-\w._()]+$'.
At line:7 char:2
+ Set-AzureRmResourceGroup -ResourceGroupName $RGName -Tag #{BUSINESS_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzureRmResourceGroup], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetA
zureResourceGroupCmdlet Set-AzureRmResourceGroup :
'resourceGroupName' does not match expected pattern '^[-\w._()]+$'.
At line:7 char:2
+ Set-AzureRmResourceGroup -ResourceGroupName $RGName -Tag #{BUSINESS_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzureRmResourceGroup], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.SetA
zureResourceGroupCmdlet
First you filtered the content of $RGInfo to only the Resource Group name, you cannot add tags to just the name
$RGInfo = Get-AzureRmResourceGroup | Where-Object {$_.ResourceGroupName -like "RG-CRP-D365*" } | Select-Object ResourceGroupName
Below syntax should work.
$RGInfo = Get-AzureRmResourceGroup | Where-Object {$_.ResourceGroupName -like "RG-CRP-D365*" }
ForEach ($RGName in $RGInfo)
{
If ($RGName.Tags -eq $null)
{
Set-AzureRmResourceGroup -ResourceGroupName $RGName.ResourceGroupName -Tag #{BUSINESS_UNIT="CRP"; COST_CENTER="6435" }
}
}
Hope this helps.
I had a similar issue when importing a list from a CSV file. Turns out the RG names had spaces on it 🤦‍♂️.

Resources