New-AzureRmWebAppBackup errors out on "master" db - powershell

I'm attempting to script an Azure Web App backup in PowerShell.
These commands:
$DatabaseBackupSetting = New-AzureRmWebAppDatabaseBackupSetting -Name $DatabaseName `
-ConnectionString $ConnectionStrings[0].ConnectionString -DatabaseType "SqlAzure"
New-AzureRmWebAppBackup -ResourceGroupName $ResourceGroupName -Name $Site -StorageAccountUrl $SasUrl `
-Databases $DatabaseBackupSetting -BackupName ($Site + "_backup_" + (Get-Date -Format FileDateTimeUniversal)).ToLower()
Should back up the site and the attached db.
Here is the connection string I'm passing in to New-AzureRmWebAppDatabaseBackupSetting:
Server=tcp:[MYSERVER].database.windows.net,1433;Initial Catalog=demo-dev;Persist Security Info=False;User ID=demoadmin;Password=[MY_PASSWORD];MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
When I run the New-AzureRmWebAppBackup command and check the status I see:
The server principal "demoadmin" is not able to access the database "master" under the current security context.
Cannot open database "master" requested by the login. The login failed.
Login failed for user 'demoadmin'.
I can't figure out how to tell the command to ignore the "master" db.
Any thoughts?

Related

Run SQL query using powershell and AAD authentication with an SSO account

I am trying to run a set of queries from Cloud Shell using powershell that require and Azure AD user. I generally use invoke-sqlcmd using the server admin and password but the specific query I want to run require an AD user. I would like to run the query as myself. I have found that I can use the ConnectionString parameter to do this, but my problem is I do not have a password as I login to Azure via SSO. I basically want to mimic the process of going to my DB in Azure, going to query editor, using AAD authentication and running a query, but with powershell. Is there a way I can do this? Example of what I am trying to do below:
$serverName = 'server'
$dbName = 'database'
$query = 'CREATE USER [AAD_User] FROM EXTERNAL PROVIDER;'
Invoke-Sqlcmd -ServerInstance $ServerName -Database $dbName -Query $query
When I attempt this I get:
Invoke-Sqlcmd: Cannot authenticate using Kerberos. Ensure Kerberos has been initialized on the client with 'kinit' and a Service Principal Name has been registered for the SQL Server to allow Kerberos authentication.
I tried to reproduce the same in my environment and got the results like below:
As SSO is enabled and you do not have a password, you can try generating access token to perform the action.
I used the below script to add the user in Azure Database:
Connect-AzAccount
$connectionString = "Server=testrukserver.database.windows.net;Initial Catalog=testdb;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30"
$accessToken = (Get-AzAccessToken -ResourceUrl https://database.windows.net).Token
$sqlConn = New-Object System.Data.SqlClient.SqlConnection
$sqlConn.ConnectionString = $connectionString
$sqlConn.AccessToken = $accessToken
$sqlConn.Open()
Invoke-Sqlcmd -ServerInstance testrukserver.database.windows.net -Database testdb -AccessToken $accessToken -query 'CREATE USER [test#xxx.onmicrosoft.com] FROM EXTERNAL PROVIDER'
$sqlConn.Close()
The user is added sccessfully in the Azure Database like below:
Reference:
Connecting to Azure SQL Database with AAD Authentication using Powershell by alex stuart

Check whether a Cosmos DB exists using PowerShell

I am trying to check whether a Cosmos DB exists or not using Powershell in Octopus. If Not I need to create it. Thats the requirement
$ApplicationShortName = "stc"
$resourceGroup = $OctopusParameters["AzurePlatform.Application[$ApplicationShortName].ResourceGroup.Name"]
$CosmosAccount = $OctopusParameters["AzurePlatform.Application[$ApplicationShortName].CosmosDbAccount.Name"]
$databaseName='sdsd'
Write-Host "Resource Group : $resourceGroup"
Write-host "Cosmos Account : $CosmosAccount"
#Check whether database exists
Get-AzCosmosDBSqlDatabase -ResourceGroupName $resourceGroup -AccountName $CosmosAccount -Name $databaseName
But here the problem is if DB actually exists, the above function works fine. But if DB not exists, it simply triggers an error.
So how to check whether the DB exists or not. So if not exists I need to fire this command
New-AzCosmosDBSqlDatabase -AccountName $CosmosAccount -Name $databaseName -ResourceGroupName $resourceGroup
You should be able to handle this process within your Octopus script - take a look at the documentation for error handling for Octopus scripts
The best practice here is to always check the exit code when invoking programs:
& ping 255.255.255.0
if ($LastExitCode -ne 0) {
throw "Couldn't find 255.255.255.0"
}
By checking the $LastExitCode, you can determine whether there was a success in your step and drive your database creation.
Also worth noting that if you use the az cli instead of the PowerShell commands, there's a specific command for what you're doing here that returns a boolean! Check out az cosmosdb database exists if you want to try and get it that way without having to manually check exit codes.

Connecting Exchange Online Fails when passing proxy and running in System PowerShell - TokenProvider Returns Object Reference Error

I was connecting Exchange Online using a PowerShell window that is opened with system access. I used PSExec on an elevated Command Prompt to open the System access PowerShell. Below is the command.
PSExec -i -s PowerShell
On the PowerShell, I imported the latest Exchange Online Management PowerShell module version 2.0.3. I use the app-based authentication described here: https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps#setup-app-only-authentication.
There is one more website that shows how to connect with app-based authentication: https://o365reports.com/2020/07/04/modern-auth-and-unattended-scripts-in-exchange-online-powershell-v2.
Below are the commands used to connect to Exchange Online.
Import-Module .\ExchangeOnlineManagement
$sessopt = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -ProxyAccessType IEConfig
$certkey = ConvertTo-SecureString "<EnterCertificateKeyHere>" -AsPlainText -Force
Connect-ExchangeOnline -CertificateFilePath "pfx Certificate Path" -AppId <EnterAppIdHere> -Organization "domain.onmicrosoft.com" -CertificatePassword $certkey -PSSessionOption $sessopt -verbose
When running the above, it returns Object Reference error. I got excited and went on to find what the error is by decompiling the DLL files and found that inside the 'ExoPowershellGalleryModule.dll -> NewExoPSSession.cs' of the Exchange module, the 'GetAccessToken' function which is called around line:308 causes this error. Any idea what makes the Object reference not set to an instance of an object. System.Management.Automation.RemoteException: Object reference not set to an instance of an object. error. Was the proxy not taken from IE?
I've set the proxy settings in IE using the below Powershell command-lets in system PowerShell.
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyServer -Value "ProxyServerAddress"
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyEnable -Value 1
Any help to resolve this is appreciated.
If your using
PSExec -i -s PowerShell
Then the proxy information your entering for the user will have no effect because the local system account will have its own profile information. Also if the proxy needs authentication you also won't be presenting any Network credentials.
If you really want to run under the system account you could try using netsh to configure the proxy https://learn.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/configure-proxy-internet but if you proxy need authentication this won't work.

How to add Managed Identity user to Azure SQL database with Powershell?

I'm trying to create a deploy script in powershell to create and configure the environment for a web application. The web app uses user-assigned Managed Identity to reach the SQL server.
I have to run the following command in the SQL server:
CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER;
But this command errors when I use sql adminstrator login: "Only connections established with Active Directory accounts can create other Active Directory users."
I add an AD administrator with Set-AzSqlServerActiveDirectoryAdministrator
But how can use this AD login from powershell to run the SQL command?
It seems that Invoke-Sqlcmd (or at least the version of it that I have) doesn't support Azure AD authentication.
I've used a PowerShell script like this to create users (you may need to update sqlcmd):
$query = "CREATE USER [$identityName] FROM EXTERNAL PROVIDER;"
sqlcmd -S $serverHostName -d $databaseName -G -N -U $username -t 120 -b -Q $query
The -G flag there tells it to use Azure AD authentication, in this case it will use interactive authentication and require you to login.
If I recall, you can use the -U and -P flags to define the username and password as well for the Azure AD user, but that'll only work if the user doesn't have MFA enabled and isn't a federated user.
Apparently the Azure AD login only works with the -ConnectionString parameter. So the solution is:
# Create User Managed Identity
$mi = New-AzUserAssignedIdentity -ResourceGroupName $resourceGroupName -Name $managedIdentityName
# Enable AD login for SQL server
Set-AzSqlServerActiveDirectoryAdministrator -ServerName $sqlServerName -ResourceGroupName $resourceGroupName -DisplayName $AdAdminUser -ObjectId $AdAdminObjectId
# Add Managed identity login to SQL server
$connectString = "Server=tcp:$sqlServerName.database.windows.net,1433;Initial Catalog=$sqlDBName;Authentication=Active Directory Password;user=$AdAdminUser;pwd=$AdAdminPw"
$query = "CREATE USER [$managedIdentityName] FROM EXTERNAL PROVIDER;"
Invoke-Sqlcmd -ConnectionString $connectString -Query $query -OutputSqlErrors $true

Azure PowerShell Get-AzureSqlDatabaseServiceObjective returns null when specifying certain Premium performance levels

I've created an Azure PowerShell script in a Runbook within the Azure Automation portal in order to automatically scale the database performance level depending on what time it is.
I can successfully retrieve a service objective via "Get-AzureSqlDatabaseServiceObjective" when I want to scale down to a "P1" or "P2" performance level; however, when I want to scale up to "P6" or "P11", I am unable to do so with the same exact block of code:
$Edition = "Premium"
$PerfLevel = "P6"
$Servercredential = new-object System.Management.Automation.PSCredential($Credential.UserName, (($Credential).GetNetworkCredential().Password | ConvertTo-SecureString -asPlainText -Force))
$CTX = New-AzureSqlDatabaseServerContext -ManageUrl “https://$ServerName.database.windows.net” -Credential $ServerCredential
$ServiceObjective = Get-AzureSqlDatabaseServiceObjective $CTX -ServiceObjectiveName $PerfLevel
Set-AzureSqlDatabase $CTX –DatabaseName $DatabaseName –ServiceObjective $ServiceObjective –Edition $Edition -Force
When I specify "P6" as the "ServiceObjectiveName" this cmdlet returns null; however, when I specify "P1" or P2" the cmdlet returns the correct ServiceObjective object, and the code will execute properly.
The MSDN documentation for "Get-AzureSqlDatabaseServiceObjective" only shows "P1, P2, P3" as valid Premium values; however, there has to be a way to scale the database to these higher performance levels (I can specify "P3" as a parameter in this script and it will actually change the database performance level to P3, even though you can't select this performance level manually through the Azure Portal anymore).
Can anyone give advice or maybe another method to achieve scaling up to these higher performance levels via a PowerShell script? I've done hours of research on here and elsewhere and I can't find a solution to this or any other post with a similar problem that was resolved.
Azure Resource Management commandlet for sql server i.e Set-AzureRmSqlDatabase can be used to upscale db to any desired edition/performance level.
We have to connect to our Azure subscription and acquire database instance to upscale it. We can create a runbook to schedule upgrade/downgrade.
# Read the subscription credentials. AzureRunAsConnection asset is created as a part of Automation account setup(see link below)
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
# Connect to the subscription (Uninteractive login).
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID `
-ApplicationId $Conn.ApplicationID `
-CertificateThumbprint $Conn.CertificateThumbprint
# Set the new performance tier of db.
Set-AzureRmSqlDatabase -DatabaseName $Using:DatabaseName `
-ServerName $Using:SqlServerName `
-ResourceGroupName $Using:ResourceGroupName `
-Edition $Using:Edition `
-RequestedServiceObjectiveName $Using:PerfLevel
Read Authentication runbook with AzureRunAsAccount for details on authentication using runbook connection asset.
NOTE: `(tick) is used to break the commandlet in multiple lines.
Here is my upgrade and downgrade example for Azure DB and Azure DWH: http://microsoft-bitools.blogspot.com/2017/04/scheduled-upgrade-and-downgrade-azure.html