Alert creation for AppInsights fails with "Code":"ResourceNotSupported" - azure-powershell

I created an App Insights in Central US region using this script:
New-AzureRmResource -ResourceName $appInsightsName -ResourceGroupName $defaultRgName -Tag #{ Name = "AppInsightsApp"; Value = $appInsightsName} -ResourceType "Microsoft.Insights/Components" -Location $defaultLocation -PropertyObject #{"Type"="ASP.NET"} -Force
Now I'm trying to add an Alert to this App Insights instance using following script:
$appInsights = Get-AzureRmResource -ResourceName $appInsightsName -ResourceGroupName $defaultRgName -ResourceType "Microsoft.Insights/Components" -Verbose
Add-AlertRule -Name "Exception Occured" -Description "Exception occured alert" -ResourceGroup $defaultRgName -ResourceId $appInsights.ResourceId -MetricName "Server Exceptions" -Operator GreaterThanOrEqual -Threshold 1 -WindowSize 00:05:00 -CustomEmails "some#email.address" -Location $defaultLocation -RuleType Metric -Verbose
And I always getting following error:
Add-AlertRule : ResourceNotSupported: The target resource id
'/subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX/resourceGroups/RG-Dev-CentralUS/providers/Microsoft.Insights/components/XXXXXX-appinsights' is not supported.
How can I fix this issue?

It looks like alert rules can be created only in East US. The same in Azure Portal - you cannot select location, but all rules are created in East US.
Try to use East US location in Powershell command:
$appInsights = Get-AzureRmResource -ResourceName $appInsightsName -ResourceGroupName $defaultRgName -ResourceType "Microsoft.Insights/Components" -Verbose
Add-AlertRule -Name "Exception Occured" -Description "Exception occured alert" -ResourceGroup $defaultRgName -ResourceId $appInsights.ResourceId -MetricName "Server Exceptions" -Operator GreaterThanOrEqual -Threshold 1 -WindowSize 00:05:00 -CustomEmails "some#email.addresss" -Location "East US" -RuleType Metric -Verbose

Azure Resources are not all available in every region or cloud type. So you will have to check before you build out your templates or execute PS create/move resource scripts.
Powershell command for checking the availability region of a resource:
$resources = Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Insights -ApiVersion "2015-05-01"
$resources.ResourceTypes.Where{($_.ResourceTypeName -eq 'components')}.Locations
You'll notice that I used the ApiVersion flag. This is going to be required since some resources are only available in regions with their newer APIs.
Because I had this same issue when deploying my ARM Templates, I needed to makes sure that my deployable region list did not include invalid values. So I generated a list of valid regions that I can deploy the following.
Microsoft.Insights/components
Microsoft.Insights/webtests
microsoft.insights/alertrules
Here is the Powershell I generated my list with. I am targeting the 2015-05-01 API as of this post.
$resources = Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Insights -ApiVersion "2015-05-01"
$components = $resources.ResourceTypes.Where{($_.ResourceTypeName -eq 'components')}.Locations
$webtests = $resources.ResourceTypes.Where{($_.ResourceTypeName -eq 'webtests')}.Locations
$alertrules = $resources.ResourceTypes.Where{($_.ResourceTypeName -eq 'alertrules')}.Locations
$components | ?{ $webtests -contains $_ } | ?{ $alertrules -contains $_ }
And the resulting list is:
East US
South Central US
North Europe
West Europe
Southeast Asia
West US 2
Canada Central
Central India

Related

Create keyvault secret - Operation returned an invalid status code 'Conflict'

I want to create multiple secrets in keyvault. Assign dynamic values of Blobstorage account, Batch account.
I tried below code to create secrets:
Function CreateKeyvaultSecrets
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $keyvaultName,
[Parameter(Mandatory=$true, Position=1)]
[string] $blobStorageAccountName,
[Parameter(Mandatory=$true, Position=2)]
[string] $batchaccountName,
[Parameter(Mandatory=$true, Position=3)]
[string] $logRgName
)
#Get Storagekey
$blobStorageKeyObject = (Get-AzStorageAccountKey -ResourceGroupName $logRgName -AccountName $blobStorageAccountName)| Where-Object {$_.KeyName -eq "key1"}
$blobStorageKey = $blobStorageKeyObject.Value
$blobStorageConnectionString = "DefaultEndpointsProtocol=https;AccountName=$blobStorageAccountName;AccountKey=$blobStorageKey;EndpointSuffix=core.windows.net"
#Create blobstorage key secret
$blobSecretkey = ConvertTo-SecureString -String $blobStorageKey -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName $keyvaultName -Name 'blobstorageaccesskey' -SecretValue $blobSecretkey
#Create blobstorage connectionstring key secret
$blobconnectionstringSecret = ConvertTo-SecureString -String $blobStorageConnectionString -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName $keyvaultName -Name 'blobstorageconnectionstring' -SecretValue $blobconnectionstringSecret
Write-host "Blob Storage Account connection string added to Keyvault secret"
}
CreateKeyvaultSecrets 'kvtevalmock' 'steval' 'abtaeval' 'rg-eval'
I am trying to execute above code from Azure DevOps Powershell task. Azure powershell version is 5.
Secrets are not getting creating. Below error is thrown:
WARNING: Upcoming breaking changes in the cmdlet 'Set-AzKeyVaultSecret' :
- The output type 'Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultSecret' is changing
- The following properties in the output type are being deprecated : 'SecretValueText'
- The change is expected to take effect from the version : '3.0.0'
Note : Go to https://aka.ms/azps-changewarnings for steps to suppress this breaking change warning, and other
information on breaking changes in Azure PowerShell.
##[error]Operation returned an invalid status code 'Conflict'
##[error]PowerShell exited with code '1'.
I test your script on my side, it works fine.
From the error message, looks your Az.KeyVault powershell module version is too old, my version is 3.4.0, try to update it with the command below.
Update-Module -Name Az.KeyVault -Force
After the update, close all the powershell sessions and open a new one to try again, it should work.

Powershell error output supression (again)

I know this has been asked more than once before - because I've searched and read them all!..
Despite that, I am fighting a particularly obstinate powershell error that seemingly just will not let me suppress outputting great wodges of red to the screen. I'm doing a simple connection to the AzureAD module with this one-liner...
Connect-AzureAD -Credential $Credential
Note that I work in the Azure tenants of many different customers, some enforce 2FA, some do not. I'm writing a bunch of helper functions to ease the day-to-day grind of logging on and off many times to different tenants...
I know that cmdlet will fail when attempting to connect to a 2FA-enforced tenant... I expect it, and I want to trap it (silently) and handle that error myself. most of which I can do, but its the 'silently' bit that is particularly troublesome. I've tried every possible method of suppressing output that I know about (mostly from the other articles on here!).
With no countermeasures taken at all, that cmdlet generates 6 (six!) error events, all of which show onscreen. Using any of the supression methods I can think of, I can suppress 5 of those, but no matter what I try, one error always still appears onscreen... I have tried:
Connect-AzureAD -Credential $Credential *> .errors.txt
Connect-AzureAD -Credential $Credential *>&1 > .errors.txt
Connect-AzureAD -Credential $Credential *>&1 | out-null
Connect-AzureAD -Credential $Credential 2>&1 | out-null
Connect-AzureAD -Credential $Credential *>$null
$void=Connect-AzureAD -Credential $Credential -ErrorAction silentlycontinue
$void=Connect-AzureAD -Credential $Credential
Connect-AzureAD -Credential $Credential >$null
Connect-AzureAD -Credential $Credential|out-null
[void](Connect-AzureAD -Credential $Credential)
So far, absolutely nothing works to completely suppress all of the error output, - I always get that last 1 error ruining my tidy screen output.
I've also checked if the Connect-AzureAD cmdlet has any options such as -quiet or -silent etc. - it does not..
FYI, the actual error thrown is:
Connect-AzureAD : One or more errors occurred.: AADSTS50076: Due to a configuration change made by
your administrator, or because you moved to a new location, you
must use multi-factor authentication to access '00000002-0000-0000-c000-000000000000'.
Trace ID: 73e00fc9-6e7b-4210-8aa6-285b04692800
Correlation ID: 1b9e2d49-1ed6-4f1e-8ce9-65761a15edd9
Timestamp: 2020-02-14 16:12:10Z
At line:1 char:1
+ Connect-AzureAD -Credential $Credential *> .errors.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-AzureAD], AadAuthenticationFailedException
+ FullyQualifiedErrorId : Microsoft.Open.Azure.AD.CommonLibrary.AadAuthenticationFailedException,Microsoft.Open.Azure.AD.CommonLibrary.ConnectAzureAD
Does anyone have any ideas for a nuclear strength option to completely suppress absolutely all output from errors? My catch block does work to trap the [Microsoft.Open.Azure.AD.CommonLibrary.AadAuthenticationFailedException] named exception, so I can deal with the error just fine, but I really want to not have that splodge of red error text 'corrupting' my output.
TIA!
Paul G.
I tend to wrap most AzureAD code with try{}catch{}. A quick test seems to work for your case:
try {
Connect-AzureAD -ErrorAction Stop
} catch {
Write-Error -Message "Login cancelled or something..."
}
Hope you find this useful.

Remove-AzureRmSqlDatabase keeps asking me to run LoginAzureRmAccount

I have an Azure SQL database which I want to delete. The command should be:
Remove-AzureRmSqlDatabase -ResourceGroupName $dbResourceGroup -ServerName $dbServerName -DatabaseName $dbToDelete -Whatif -Force
The error I keep getting back is
Remove-AzureRmSqlDatabase : Run Login-AzureRmAccount to login.
I tried running Login-AzureRmAccount as myself, then as a service principal I use for unattended scripts, and nothing worked.
I am able to log into the Azure RM portal and delete databases. I am also able to run Invoke-SqlCmd against this database to query and manipulate data.
How can I make this work?
According to this error message, it seems that you have not login Azure whit the right subscription.
We can use this command to get the sql database's information, and check the subscription.
(Get-AzureRmSqlDatabase -DatabaseName jasontest1 -ServerName jasontest -ResourceGroupName jasontest).resourceid
Then we can find the subscription in the powershell output.
PS C:\Users> (Get-AzureRmSqlDatabase -DatabaseName jasontest1 -ServerName jasontest -ResourceGroupName jasontest).resourceid
/subscriptions/5384xxxx-xxxx-xxxx-xxxx-xxxxe29axxxx/resourceGroups/jasontest/providers/Microsoft.Sql/servers/jasontest/databases/jasontest1
To find which subscription, we can use this command Get-AzureRmSubscription to list it:
PS C:\Users> Get-AzureRmSubscription
Name : Visual Studio Ultimate with MSDN
Id : 5384xxxx-xxxx-xxxx-xxxx-xxxxe29axxxx
TenantId : 1fcfxxx-xxxx-xxxx-xxxx9-xxxx8bf8xxxx
State : Enabled
Also we can use this command to select the subscription:
Get-AzureRmSubscription -SubscriptionId 5384xxxx-xxxx-xxxx-xxx-xxxxe29axxxx
My Powershell Azure modules had dependency errors for something. To fix it I (at the behest of Microsoft tech support) ran:
PS C:\> Install-Module AzureRM -Force
This re-installed it and fixed the dependency problems.

TFS Build variable current sprint TFS 2015

We have a CI build server doing automated builds and would like to include the current sprint/iteration number in the assembly version. Is there an environment variable or easy way of getting the current sprint number in the build processes? TFS On Permise 2015 Update 3
There isn’t build-in variable to get current sprint, but you can use REST API.
Steps:
Add a PowerShell file to the source control (e.g. included in your project and check in)
Code:
Param(
[string]$collection,
[string]$projectName,
[string]$token
)
$uri="$collection/$projectName/_apis/work/teamsettings/iterations?`$timeframe=current&api-version=v2.0-preview"
Write-Output $uri
$result = Invoke-RestMethod -Uri $uri -Method Get -Headers #{Authorization=("Bearer {0}" -f $token)}
Write-Output "success"
Write-Output $result.value.path
Write-Host "##vso[task.setvariable variable=currentSprint;]$($result.value.path)"
Edit your build definition
Click Options tab and check Allow Scripts to Access OAuth Token
Add PowerShell build step and specify PowerShell file (step 1) (arguments: -collection $(System.TeamFoundationCollectionUri) -projectName $(System.TeamProject) -token $(System.AccessToken) )
After that, the current sprint value is stored in currentSprint variable.

The specified module 'WebAdministration' was not loaded (Windows 2003, IIS 6)

I am trying to run some IIS admin scripts on machine with -
OS - Windows 2003(with SP2)
IIS - V6.0
Powershell - V2
However when I run following commands, I get the error -
- Import-Module WebAdministration
**Error**:
Import-Module : The specified module 'WebAdministration' was not loaded because no valid module file was found in any module directory.
At line:1 char:14 + Import-Module <<<< WebAdministration
+ CategoryInfo : ResourceUnavailable: (WebAdministration:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
- Add-PSSnapIn WebAdministration
**Error:**
Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2.
At line:1 char:13 + Add-PSSnapIn <<<< WebAdministration
+ CategoryInfo : InvalidArgument: (WebAdministration:String) [Add-PSSnapin], PSArgumentException
+ FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand
I checked which modules/snapin are available - here is the result -
Get-Module -ListAvailable
Result:
BitsTransfer
Get-PSSnapIn
Result:
Microsoft.PowerShell.Diagnostics
Microsoft.WSMan.Management
Microsoft.PowerShell.Core
Microsoft.PowerShell.Utility
Microsoft.PowerShell.Host
Microsoft.PowerShell.Management
Microsoft.PowerShell.Security
Please guide what shall I do to run IIS administration scripts.
Below link says Powershell SnapIn is not available for IIS 6.0:
http://forums.iis.net/p/1156851/1903821.aspx#1903821
WMI is the option to go with IIS 6.0 administration.
But WMI is not the option for me as soon we will be upgrading to IIS 7.5
In IIS6 on Windows 2k3 platform, I suggest you try accessing IIS via the old WMI provider ("Microsoftiisv2") or ADSI provider as both are accessible from the PowerShell.
Neither snapins nor WebAdministration module is available for IIS 6.0, so we can access IIS6 metabase from PowerShell using either
For IIS7.0, we can "import WebAdministration" module.
For example, I had to set the physical path for a virtual directory for IIS6, so I made use of a vbs script,iisvdir that comes along with IIS6 in c:/Windows/System32 .
Copying the code snippet
Function resetSiteLocation ($newPath)
{
Write-Host "List of Virtual directories for the site Test123 before reset :"
C:\WINDOWS\system32\iisvdir /query Test/Test123
Write-Host "About to reset site location"
C:\WINDOWS\system32\iisvdir /delete Test/Test123/Test1
C:\WINDOWS\system32\iisvdir /create Test/Test123 Test1 C:\projects\Test\Test123\Test1
C:\WINDOWS\system32\iisvdir /delete Test/Test123/Test2
C:\WINDOWS\system32\iisvdir /create Test/Test123 Test2 C:\projects\Test\Test123\Test2
Write-Host "Finished to reset site location"
Write-Host "List of Virtual directories for the site Test123 after reset :"
C:\WINDOWS\system32\iisvdir /query Test/Test123
}
Since you would be making a switch to higher version of IIS, you could put a switch in your code to determine the IIS version and take action as appropriate.
I did this:
Write-Host "Checking Installed IIS version:"
$iisVersion = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp";
Write-host IIS major version : $iisVersion.MajorVersion
Write-host IIS minor version : $iisVersion.MinorVersion
Write-Host "Finished the check."
## IIS inclusion module
## Neither snapins nor WebAdministration module is available for IIS 6.0, so we can access IIS6 metabase
## from PowerShell using either old WMI provider ("Microsoftiisv2") or ADSI provider as both are accessible from the PowerShell.
## For IIS7.0, we can import WebAdministration module
if (($iisVersion.MajorVersion -eq 7 ) -or ($iisVersion.MajorVersion -ge 7 ))
{
Write-host Detected IIS Major Version : $iisVersion.MajorVersion and Minor version : $iisVersion.MinorVersion. Hence importing WebAdministration module.
Import-Module WebAdministration;
Write-Host "About to reset app pool"
Restart-WebAppPool("Application")
Write-Host "Finished resetting app pool"
resetSiteLocation
Write-Host "About to reset site"
Restart-WebItem("IIS:\Sites\My application")
Write-Host "Finished to reset site"
}
elseif ($iisVersion.MajorVersion -eq 6)
{
Write-host IIS version 6 detected. Hence accessing IIS metabase using old WMI provider
##2. Reset App Pool
Write-Host "About to reset app pool"
Write-Host "Finished resetting app pool"
##3. Reset site location
resetSiteLocation
##4.Reset site
Write-Host "About to reset site"
Write-Host "Finished to reset site"
}
else
{
Write-host Detected IIS $iisVersion.MajorVersion
}
Let me know if it helps you.
Here is some good information on using the WMI interface with IIS 6:
http://network-nick.blogspot.com/2015/01/powershell-and-iis-6.html
He also points to the Microsoft documentation of cmdlets for this environment, here:
https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525265(v=vs.90)
During the article he develops and explains the following PowerShell script for listing a server's web sites and their virtual directories. I actually tried this and it works.
$WebSiteID = Get-WmiObject -Namespace "root/MicrosoftIISv2" -Class IIsWebServer | Select-Object -ExpandProperty Name
ForEach ( $Site in $WebSiteID ) {
$WebSiteName = Get-WmiObject -Namespace "root/MicrosoftIISv2" -Class IIsWebServerSetting | Where-Object { $_.Name -like "$site" } `
| Select-Object -Expandproperty ServerComment
write-host "`r`n" $WebSiteName
$AppPath = Get-WmiObject -Namespace "root/MicrosoftIISv2" -Class IIsWebVirtualDirSetting | Where-Object { $_.Name -like "$site/*" } `
| select -expandproperty path
$AppPath = $AppPath | select-object -unique | sort-object
$AppPath
}