Parameters for my Azure Workbook was incorrect - powershell

Login-AzureRmAccount
$params = #{SqlServerName="myServer";SqlDatabaseName="myDb";SqlUserName="myDbUser"}
Register-AzureRmAutomationScheduledRunbook `
–Name "AutoExport" `
-ResourceGroupName "myAzureAutomation" `
–AutomationAccountName "myAutomation" `
–ScheduleName "myScedule" `
–Parameters $params `
-ErrorAction Stop;
And when I go on the Azure Portal parameters contain quoted string
Example:
Eventually my Workbook will crash because values expected no quotes. I know, I can remove quotes into script of my Workbook but it seem to me that is not an elegant solution.
What I doing wrong!

Related

Add-AzKeyVaultNetworkRule on Powershell script throwing error

I need to add the Outbound IPs of Azure Function-App to Azure KeyVault Firewall Rule to be whitelisted, using powershell, to be executed on a pipeline. My script is :
param(
[Parameter()]
[String]$resourcegrp,
[String]$funcname,
[String]$kv
)
$functionApp = Get-AzFunctionApp -ResourceGroupName $resourcegrp -Name $funcname
Add-AzKeyVaultNetworkRule -VaultName $kv -ResourceGroupName $resourcegrp `
-IpAddressRange ($functionApp.PossibleOutboundIPAddress).Trim()
Update-AzKeyVaultNetworkRuleSet -VaultName $kv -ResourceGroupName $resourcegrp `
-DefaultAction Deny -Bypass AzureServices `
-IpAddressRange ($functionApp.PossibleOutboundIPAddress).Trim()
The above is giving below error:
where as if I do the same on powershell prompt like below, it works fine.
Can someone suggest what's wrong in my PS1 file, or what can be a better way to achieve the same with a PowerShell script.
This is because the property $functionApp.PossibleOutboundIPAddress is a single string
$functions[0].PossibleOutboundIPAddress | gm
TypeName: System.String
But Add-AzKeyVaultNetworkRule expects a string array
Get-Help Add-AzKeyVaultNetworkRule -Parameter ipaddressrange
-IpAddressRange <System.String[]>
Specifies allowed network IP address range of network rule.
You should be able to make this work by splitting the value from the functionApp on the , delimiter
$addAzKeyVaultNetworkRuleSplat = #{
VaultName = $kv
ResourceGroupName = $resourcegrp
IpAddressRange = $functionApp.PossibleOutboundIPAddress -split ','
}
Add-AzKeyVaultNetworkRule #addAzKeyVaultNetworkRuleSplat

Failure when creating service fabric cluster with powershell

I'm trying to create a service fabric cluster with a powershell script. Here's the script:
Param(
[Parameter(HelpMessage="Azure user name")]
[String]$azUserName,
[Parameter(HelpMessage="Azure password")]
[String]$azPassword,
[Parameter(HelpMessage="What is the resource group name?")]
[String]$ResourceGroupName="sfLinuxClusterRg",
[Parameter(HelpMessage="What is the key vault group name?")]
[String]$KeyVaultResourceGroupName="KeyVaultRg",
[Parameter(HelpMessage="Where is the azure location?")]
[String]$Location="uksouth",
[Parameter(HelpMessage="what is the key vault group?")]
[String]$VaultGroupName="linuxclusterkeyvaultgroup",
[Parameter(HelpMessage="Where is the certificate stored locally?")]
[String]$CertFileName="certificate.pfx",
[Parameter(HelpMessage="What is the subscription id?")]
[String]$SubscriptionId,
[Parameter(HelpMessage="What is the tenant id?")]
[String]$TenantId
)
Function DecryptSecureString([SecureString] $secureText){
return [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureText))
}
Function CreateKeyVaultCert(){
try{
Select-AzureRmSubscription -SubscriptionId $SubscriptionId `
-TenantId $TenantId
# Create a Resource Group to hold your Key Vault(s)
# Note this should be separate from your other resources so you can delete those other resource groups without impacting your registered certs
New-AzureRmResourceGroup -Name $KeyVaultResourceGroupName -Location uksouth -Force
# Create a Key Vault to hold your secrets
New-AzureRmKeyVault -VaultName $vaultName -ResourceGroupName $KeyVaultResourceGroupName `
-Location uksouth -EnabledForDeployment `
-EnabledForDiskEncryption -EnabledForTemplateDeployment
# Have Key Vault create the certificate with a simple policy
$policy = New-AzureKeyVaultCertificatePolicy `
-SubjectName "CN=cluster123.uksouth.cloudapp.azure.com" `
-IssuerName Self -ValidityInMonths 12
Add-AzureKeyVaultCertificate -VaultName $vaultName -Name cert1 -CertificatePolicy $policy
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -EnabledForDeployment
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -EmailAddress $azUserName -PermissionsToSecrets Get
}
catch{
Write-Host $_.Exception.Message
exit
}
}
$azPassword = $azPassword | ConvertTo-SecureString -AsPlainText -Force
Import-AzureRmContext -Path "C:\stuff\AzureProfile.json"
$Date = Get-Date
$VaultName="VaultLearn" + $Date.ToString("hhmmss")
# sign in to your Azure account and select your subscription
$certName = "CN=cluster123.uksouth.cloudapp.azure.com"
$clustersize=5
$clustername = "cluster123" + $Date.ToString("hhmmss")
$adminuser="admin"
$vmsku = "Standard_D2_v2"
$os = "UbuntuServer1604"
Select-AzureRmSubscription -SubscriptionId $SubscriptionId
CreateKeyVaultCert
New-AzureRmServiceFabricCluster -Name $clustername `
-ResourceGroupName $ResourceGroupName `
-Location uksouth `
-ClusterSize $clustersize `
-VmUserName $adminuser -VmPassword $azPassword `
-CertificateSubjectName $certName `
-CertificatePassword $azPassword `
-VmSku $vmsku `
-CertificateOutputFolder 'C:\stuff' `
-OS $os `
-KeyVaultName $VaultName
Write-Host "Created service fabric cluster in resource group $ResourceGroupName"
#Add-AzureRmAccount
# $path = "C:\stuff\AzureProfile.json"
# Save-AzureRmContext -Path $path -Force
I keep getting the error:
New-AzureRmServiceFabricCluster : The name 'VaultLearn090903' is already in use.
This is really weird, because I'm pretty sure yesterday this script at least attempted to create the cluster, although I was getting another error about Ubuntu image not being found. What could be causing this error?
By the way, in order to run this script, I have previously run this code:
Add-AzureRmAccount
$path = "C:\stuff\AzureProfile.json"
Save-AzureRmContext -Path $path -Force
which has cached my azure credentials locally.
I have specifically added two statements into the script to add a policy for access to the keyvault:
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -EnabledForDeployment
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -EmailAddress $azUserName -PermissionsToSecrets Get
I know this is probably overkill, but I'm trying to get rid of this problem.
The other weird thing is I have tried the Azure Sample Github repo
I'm at a loss for how I can continue with service fabric.
For completeness:
I managed to get something different working by going to the azure portal, creating a service fabric cluster and downloading the ARM template (which includes some powershell scripts).
thanks

Change WebApp AppSetting values when creating a new Slot

When creating a new Slot for an Azure WebApp, how can I successfully change one or more of the AppSettings?
The docs for New-AzureRmWebAppSlot suggest that there is a parameter called -AppSettingsOverrides, but that does not work.
It should be noted however that the linked docs seem to incorrectly reference the New-AzureRmWebApp Cmdlet, so I can't be sure if the parameter is actually valid (although it seems to be accepted without error).
Here is the code that I am running.
New-AzureRmWebAppSlot -ResourceGroupName $resourceGroupName -Name $webAppName -Slot $slotName -AppSettingsOverrides #{"FUNCTION_APP_EDIT_MODE" = "readwrite"} -ErrorAction Stop
Has anyone else experienced this seemlying incorrect behaviour, and if so, how did you fix it?
My Azure version is 3.5.0.
You could create Slot firstly, then use Set-AzureRmWebAppSlot to change AppSetting. Following script works for me.
$myResourceGroup = "shuiapp"
$mySite = "shuicli"
$slotName = "Test1"
$webApp = Get-AzureRMWebAppSlot -ResourceGroupName $myResourceGroup -Name $mySite -Slot $slotName
$appSettingList = $webApp.SiteConfig.AppSettings
$hash = #{}
ForEach ($kvp in $appSettingList) {
$hash[$kvp.Name] = $kvp.Value
}
$hash['ExistingKey2'] = "NewValue12"
Set-AzureRMWebAppSlot -ResourceGroupName $myResourceGroup -Name $mySite -AppSettings $hash -Slot $slotName
The question will be helpful.
Credit to this dingmeng-xue on Github for pointing this out but for the benefit of everyone reading Stackoverflow, it appears that the cmdlet doesn't a) check that -SourceWebApp and -AppSettingsOverrides are set together and b) only does a null check if $SourceWebApp is defined and silently does nothing even if $AppSettingsOverrides was defined. So you might set them both and test if that solves the issue.

A positional parameter cannot be found that accepts argument when running New-AzureQuickVM

I've the following PowerShell script:
Param(
$AccountName = "AccountName",
$Guid = "Get-Random",
$ImageName = "ImageName",
$vmName = "VM-$Guid",
$ServiceName = "ServiceName",
$adminLogin = "adminLogin",
$adminPasswd = "adminPasswd!",
$location = "South Central US",
$instanceSize = "Medium",
$subscriptionDataFile = "file.publishsettings"
)
########################Import Azure Public Setting And Assign Storage###########################
Import-AzurePublishSettingsFile $subscriptionDataFile
Set-AzureSubscription -SubscriptionName $AccountName -CurrentStorageAccountName scrprod -PassThru
#########################Create A VM From Existing Image And Remove It##########################
for($i=1; $i -le 5; $i++)
{
New-AzureQuickVM –Windows –Location $location –ServiceName $ServiceName `
–Name $vmName –InstanceSize $InstanceSize –ImageName $ImageName–AdminUsername $adminLogin –Password $adminPasswd -WaitForBoot
})
and I get the following exception:
New-AzureQuickVM : A positional parameter cannot be found that accepts argument 'â€Windows â€Location'.
What am I doing wrong?
Second I'd like to create 5 VM's with a unique name - Is that the correct way to do it?
Thanks,
Oren
I believe the encoding of your text file is incorrect, or you are using the incorrect characters (perhaps from a cut and paste).
Your code
New-AzureQuickVM –Windows –Location
Is somehow being evaluated as
New-AzureQuickVM 'â€Windows â€Location'
I suggest deleting the - characters before Windows and Location (and elsewhere likely) and then re-typing it. Also check your file's encoding and character set.
You have formatting errors in the call of the New-AzureQuickVM cmdlet, most notably the backtick after $ServiceName could cause issues if not immediately followed by a new line. Also, there should be a space between $ImageName and -AdminUsername.
I terms of the guid, I would create one using $guid = ([guid]::NewGuid()).ToString() but really the definition of random is up to you.

Azure: How to check storage account exists in Azure with Get-AzureStorageAccount

I am building a power shell script to automate the setup of a website environment in Azure. This web uses an account storage. I want to the script not to create the account storage if exists.
I thought that using Get-AzureStorageAccount this way may work but it does not:
Write-Verbose "[Start] creating $Name storage account $Location location"
$storageAcct = Get-AzureStorageAccount –StorageAccountName $Name
if (!$storageAcct)
{
$storageAcct = New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
if ($storageAcct)
{
Write-Verbose "[Finish] creating $Name storage account in $Location location"
}
else
{
throw "Failed to create a Windows Azure storage account. Failure in New-AzureStorage.ps1"
}
}
else
{
Write-Verbose "$Name storage account in $Location location already exists, skipping creation"
}
The issue is I don't know how to handle the return of Get-AzureStorageAccount.
Thank you very much in advance!
I would suggest using the Test-AzureName cmdlet to determine if it exists. So, something like this.
if (!(Test-AzureName -Storage $Name))
{
Write-Host "Creating Storage Account $Name"
New-AzureStorageAccount -StorageAccountName $Name -Location $Location
}
You can use Test-AzureName for other services too, such as Cloud Services, WebSites, and ServiceBus. It returns True if it exists, False otherwise.
Get-AzureRmStorageAccountNameAvailability -Name "accountname"
Try this:
$Name = "myStorageAccount"
$Location = "myLocation"
Write-Host "[Start] creating $Name storage account $Location location"
try{
Get-AzureStorageAccount –StorageAccountName $Name -ErrorAction Stop | Out-Null
Write-Host "$Name storage account in $Location location already exists, skipping creation"
}
catch{
Write-Host "[Finish] creating $Name storage account in $Location location"
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
}
Test-AzureName didn't work with our build agents and we already had a try/catch in code so a second one would require building it out as a function. I opted for that standard get and check if null, use -ErrorAction Ignore to stop it throwing an exception
# Check for storage account and create if not found
$StorageAccount = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $StorageAccountRG -ErrorAction Ignore
if ($StorageAccount -eq $null)
{
New-AzureRmStorageAccount -Location "West Europe" -Name $StorageAccountName -ResourceGroupName $StorageAccountRG -SkuName Standard_LRS -Kind Storage
$StorageAccount = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $StorageAccountRG
}
#Rick Rainey's solution works if you're logged in using Add-AzureAccount. However, Azure and powershell have a conflicting and confusing suite of login accounts (Windows Live versus AD) and login mechanisms (Classic: Add-AzureAccount; Resource manager: Login-AzureRmAccount). Some Azure powershell cmdlets require a specific login; further, some require a specific account type!
To clear through this thicket of complicated, undocumented, and confusing permission issues, we always use an AD account, logging in via Login-AzureRmAccount. We also use Azure resource manager (ARM) resources and cmdlets, following Microsoft's movement to ARM as its recommended and strategic approach. However, #RIck's solution is one which the ARM login doesn't work with. :-( So you need another approach, which is #Darren's (for storage). However, for a generic replacement for Test-AzureName I'd suggest Find-AzureRmResource. In the case of storage
$StorageObject = Find-AzureRmResource -ResourceType "Microsoft.Storage/storageAccounts" | Where-Object {$_.Name -eq $storageName}
if ( !$StorageObject ) {
$storageLocation = (Get-AzureRmResourceGroup -ResourceGroupName $resourceGroup).Location
$storageType = "Standard_LRS"
New-AzureRmStorageAccount -ResourceGroupName $resourceGroup -Name $storageName -Location $storageLocation -Type $storageType
}
You should use the latest Powershell module Az.
if ($(Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName) -eq $null)
{
# does not exist
}
With the current Az module for PowerShell Version 7, the Get-AzStorageAccountNameAvailability cmdlet might offer a more efficient solution as it was designed specifically for this task. Here is an example:
# ... declare variables and specify values ...
$checkNameAvail = (Get-AzStorageAccountNameAvailability -Name $storageAccountName) | `
Select-Object NameAvailable
if ($checkNameAvail.NameAvailable)
{
Write-Host 'Account name available! Please wait while your resource is being created'
# Create account. Variables used in this example would have been declared earlier in the script.
$storageAccount = (New-AzStorageAccount -ResourceGroupName $resourceGroupName `
-AccountName $storageAccountName `
-Location $location `
-SkuName $skuType `
-AllowBlobPublicAccess $false -EnableHttpsTrafficOnly $true)
# ...
}
else
{
# This section of the script executes if the name is not available
Write-Host "The name <$storageAccountName> is not available. Suggest a new globally unique name!"
}
The condition above will return False, and execute the else statement because the boolean value returned by the cmdlet is in [0] as shown in the PowerShell command-line test below. The availability information (boolean) can thus be stripped from the object returned by the cmdlet and (as in this example) used as a condition in the rest of the script.
PS C:\> Get-AzStorageAccountNameAvailability -Name testaccount1
NameAvailable Reason Message
------------- ------ -------
False AlreadyExists The storage account named testaccount1 is already taken.
Use the error variable
Get-AzStorageAccount -ResourceGroupName 'RG-QA-TEST' -Name 'staccountfor12334ff' -ErrorVariable ev1 -ErrorAction SilentlyContinue
if ($ev1) {
Write-Host "-------------------------- Creating OEM Storage"
//create storage account
}
I had this challenge when setting up Azure storage accounts for Static website hosting using Powershell in Octopus Deploy.
Here's how I fixed it:
Using the Az module for Azure Powershell I did the following:
# Define Variables
$RESOURCE_GROUP_NAME = my-resource-group
$LOCATION = northeurope
$STORAGE_ACCOUNT_NAME = myapplication
$SKU_NAME = Standard_GRS
$STORAGE_KIND = StorageV2
# Check Storage Account and Create if not Found
$STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $RESOURCE_GROUP_NAME -Name $STORAGE_ACCOUNT_NAME -ErrorAction Ignore
if ($STORAGE_ACCOUNT -eq $null) {
Write-Host 'Creating storage account'
New-AzStorageAccount -ResourceGroupName $RESOURCE_GROUP_NAME -AccountName $STORAGE_ACCOUNT_NAME -Location $LOCATION -SkuName $SKU_NAME -Kind $STORAGE_KIND
Write-Host "$STORAGE_ACCOUNT_NAME storage account successfully created"
}
else {
Write-Host "$STORAGE_ACCOUNT_NAME storage account already exists"
}
Note:
-ErrorAction Ignore - This ignores the exception that would arise if the storage account does not exist
Write-Host " " - Double quotes were used to allow for string interpolation since we are connecting strings and variables.
That's all.
I hope this helps