how can i run this script automatically on azure for DTU - sql

$ServiceObjective = Get-AzureSqlDatabaseServiceObjective -ServerName exampledb-ServiceObjectiveName S0
Set-AzureSqlDatabase -DatabaseName exampledb-ServerName exampledb-ServiceObjective $ServiceObjective
I can run above script to make my sql database S0 DTU level,
Can i make this automatically.
BTW i searched on forums and stackoverflow,
they recommend automation account and runebook.
But i dont have RunAsAccount. I dont have admin privileges and i cant create RunAsAccount. So i couldnt use runbook.
can you recommend me another way ?
Thanks :)

But i dont have RunAsAccount. I dont have admin privileges and i cant create RunAsAccount. So i couldnt use runbook.
If you want to create an Automation account with run as account, you need to have Owner role in your subscription, because when creating the run as account(service principal), it will automatically add the service principal in your subscription as a Contributor, it just can be done with Owner.
But if you just want to use the runbook in automation account, you don't need the Owner role. You just need to ask the Owner in your subscription to create an automation account with run as account for you, then you will be able to create a powershell runbook and run your command above with e.g. Contributor role.
After the Owner creating the automation account for you, follow the steps below.
1.Navigate to the automation account -> Runbooks -> Create a runbook -> create a Powershell runbook.
2.The two commands Get-AzureSqlDatabaseServiceObjective, Set-AzureSqlDatabase, you are using belong to Azure i.e. ASM powershell module, it is old, and if you want to use them, you need to use Azure Classic Run As Account(which is not supported in CSP subscription). So I recommend you to use the new Az powershell module. In your automation account -> Modules, check if there are Az.Accounts and Az.Sql module, if not, in the Modules -> Browse Gallery, search for the modules and import them.)
After importing successfully, use the script as below to login and set the sql db with Standard S0.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Connect-AzAccount `
-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
}
}
Set-AzSqlDatabase -ResourceGroupName "<resource-group-name>" -DatabaseName "<database-name>" -ServerName "<server-name>" -Edition "Standard" -RequestedServiceObjectiveName "S0"
3.If you want to run the script automatically with a schedule, you can follow this link Scheduling a runbook in Azure Automation to do that.

Related

How do I know what user my ADO pipeline is using?

I'm using Azure DevOps pipelines, and have a PowerShell task that runs stuff with Invoke-Sqlcmd. The PowerShell works fine when run from my computer, but when it runs through the pipeline it says it can't find or doesn't have access to the server. I don't see anything in the failed connection logs on my sql servers...
I assume whatever account the pipeline is attempting to connect under does not have access. How can I find out what that account is?
If you're curious, here's the simple PS, it just updates a table:
Invoke-Sqlcmd -ServerInstance "myremoteserver" -Query "--update the table"
You can add a powershell task to run below script to get the current user account that your pipeline is using
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name

Backup Azure SQL DB during VSTS Release

I am exploring VSTS Release Management and I wanted to backup my production database hosted on Azure SQL DB before I apply any migration scripts to it. I fail to find any particular task or preferred way of waiting till the Azure SQL DB is fully backed up so that I can proceed with deployment only after the database is correctly backed up. 
I have looked at either using a PowerShell task or Azure SQL CMD task, but I am not sure how to make rest of the tasks wait for the backup to complete. 
Would appreciate if anyone could point me in the right direction. Thanks. 
You can backup Azure SQL database and check the status in a loop.
$exportRequest = New-AzureRmSqlDatabaseExport -ResourceGroupName $ResourceGroupName -ServerName $ServerName `
-DatabaseName $DatabaseName -StorageKeytype $StorageKeytype -StorageKey $StorageKey -StorageUri $BacpacUri `
-AdministratorLogin $creds.UserName -AdministratorLoginPassword $creds.Password
$importStatus = Get-AzureRmSqlDatabaseImportExportStatus -OperationStatusLink $importRequest.OperationStatusLink
[Console]::Write("Exporting")
while ($importStatus.Status -eq "InProgress")
{
$importStatus = Get-AzureRmSqlDatabaseImportExportStatus -OperationStatusLink $importRequest.OperationStatusLink
[Console]::Write(".")
Start-Sleep -s 10
}
[Console]::WriteLine("")
$importStatus
More information, you can refer to Export an Azure SQL database to a BACPAC file.
Another way is that you can backup Azure SQL database by call Microsoft.SqlServer.Dac.DacServices.ExportBacpac method with PowerShell.
param([string]$ConnectionString, [string]$DatabaseName,[string]$OutputFile,[string]$s)
Add-Type -Path "$s\AzureDatabaseSolution\SQLDatabase\lib\Microsoft.SqlServer.Dac.dll"
$now = $(Get-Date).ToString("HH:mm:ss")
$Services = new-object Microsoft.SqlServer.Dac.DacServices $ConnectionString
Write-Host "Starting at $now"
$Watch = New-Object System.Diagnostics.StopWatch
$Watch.Start()
$Services.ExportBacpac($OutputFile, $DatabaseName)
$Watch.Stop()
Write-Host "Backup completed in" $Watch.Elapsed.ToString()
Note: Using the assembly in this package: Microsoft.SqlServer.Dac 1.0.3 (I add it to the source control and map to build agent)
On the other hand, to add firewall rule, you can refer to this thread: Deploy Dacpac packages via power shell script to Azure SQL Server.
BTW, you can build the custom build/release step/task with these PowerShell scripts. Add a build task
Azure SQL Databases are continually backed up automatically. If you are trying to create a copy of the database or archive the database to a BACPAC file, you can do either.
https://learn.microsoft.com/en-us/azure/sql-database/sql-database-automated-backups
https://learn.microsoft.com/en-us/azure/sql-database/sql-database-copy
https://learn.microsoft.com/en-us/azure/sql-database/sql-database-export

Create AD application with VSTS task

I am trying to create a VSTS task, which should create an AD application.
Taken the DeployAzureResouceGroup as a sample, I have created to following script:
[CmdletBinding()]
param()
Trace-VstsEnteringInvocation $MyInvocation
Import-VstsLocStrings "$PSScriptRoot\Task.json"
$connectedServiceNameSelector = Get-VstsInput -Name "connectedServiceNameSelector" -Require
$connectedServiceName = Get-VstsInput -Name "connectedServiceName"
$connectedServiceNameClassic = Get-VstsInput -Name "connectedServiceNameClassic"
$domains = (Get-VstsInput -Name "domains").Split(";")
$appName = Get-VstsInput -Name "appName"
if($connectedServiceNameSelector -eq "ConnectedServiceNameClassic")
{
$connectedServiceName = $connectedServiceNameClassic
$action = $actionClassic
$resourceGroupName = $cloudService
}
Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_
Initialize-Azure
# Import the loc strings.
Import-VstsLocStrings -LiteralPath $PSScriptRoot/Task.json
# Import all the dlls and modules which have cmdlets we need
Import-Module "$PSScriptRoot\DeploymentUtilities\Microsoft.TeamFoundation.DistributedTask.Task.Deployment.Internal.psm1"
Import-Module "$PSScriptRoot\DeploymentUtilities\Microsoft.TeamFoundation.DistributedTask.Task.Deployment.dll"
# Load all dependent files for execution
. "$PSScriptRoot\Utility.ps1"
try
{
Validate-AzurePowerShellVersion
$azureUtility = Get-AzureUtility "$connectedServiceName"
Write-Verbose "Loading $azureUtility"
. "$PSScriptRoot\$azureUtility"
Write-Output "test"
Write-Output "Creating a new Application in AAD (App URI -)" -Verbose
$azureAdApplication = New-AzureRmADApplication -DisplayName "test" -IdentifierUris "https://app.com" -HomePage "https://app.com"
$appId = $azureAdApplication.ApplicationId
Write-Output "Azure AAD Application creation completed successfully (Application Id: $appId)" -Verbose
Write-Verbose "Completing Azure Resource Group Deployment Task" -Verbose
}
catch
{
Write-TaskSpecificTelemetry "UNKNOWNDEP_Error"
throw
}
When I use a Service principal as Service Endpoint user, I got the error Resource me not found.
When I use my custom AD account, I got the error:Run Login-AzureRmAccount to login.
What am I doing wrong? How can I get this script working?
If you don't need Powershell scripting, go install Azure AD Application Management extension from https://marketplace.visualstudio.com/items?itemName=RalphJansen.Azure-AD-Application-Management
You can add new tasks from pipeline GUI for managing AD applications.
If you do need Powershell scripting, then things get tricky.
Get Powershell code from https://stackoverflow.com/a/51848069/1548275 as a base. The difference is, that if you're not running your code from an extension, you don't have Get-VstsInput nor Get-VstsEndpoint available to execute.
Also, you don't have AzureAD module cmdlets to run. You need to get the Nuget-package, unzip it to your own repo and have it as part of your scripts to be later Import-Module in a pipeline task.
Finally, you need an auth token for Graph API. As the extension code shows, you will need 3 variables:
$tenantId = (Get-AzureRmSubscription).TenantId
$clientId = (Get-AzureRmADServicePrincipal -DisplayName "Your Project Service Connection name from Azure AD App Registrations").ApplicationId.Guid
$clientSecret = 'hard-coded, reset SPN password'
As you can see, an extension would have access to all three, but regular script (to my knowledge) doesn't.
SPN password reset is covered in The Net. Briefly, it is something like this:
$clientId = (Get-AzureRmADServicePrincipal -DisplayName "Your Project Service Connection name from Azure AD App Registrations").Id.Guid
$password = ConvertTo-SecureString –asplaintext –force "oh, this is very secret!"
New-AzureRmADSpCredential -ObjectId $clientId -Password $password
Also: Update the plaintext password into Azure DevOps project settings, Service Connections for Pipeline to know about the update.

How to run a Powershell Script block with elevated privileges

I am writing a PowerShell script to archive compressed C2 Audit files to a file share. What is possibly the last problem I am having is giving the .Net compression routine the privilege to manipulate the files. During development, I could flaunt my account's admin role to propagate Full Access privileges to the files in the DATA directory. However, the script is to run from a PowerShell step in an Agent job, and I want to automate the ACL change as well.
For an added level of difficulty, I am doing this under SQL Server 2012, so I am stuck with PowerShell 2.0. I am using .Net 4.5 compression routines via a process of loading $RunActivationConfigPath with a temporary config file. I was not able to find a way to change that config file to promote the admin role, though.
This is a segment of a script by Benjamin Armstrong that checks if the connection is using Administrator privileges.
# Get the ID and security principal of the current user account
$runtimeWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$runtimeWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($runtimeWindowsID);
# Get the security principal for the administrator role
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;
Write-Output ("Running under "+$runtimeWindowsID.Name)
Write-Output ("PS Version "+$PSVersionTable.PSVersion.Major)
# Check to see if we are currently running as an administrator
if ($runtimeWindowsPrincipal.IsInRole($adminRole) -eq $true) {
Write-Output "We are strong."
} else {
Write-Output "We are not strong."
}
Running the script as an Agent Job step produces:
Running under NT Service\SQLSERVERAGENT
PS Version 2
We are not strong.
Running the script from sqlps in Admin mode produces:
Running under DOMAIN\myusername
PS Version 2
We are strong.
All the ways I've seen to elevate a script involve using a script file. For example, creating a new process and executing it with RunAs as the Verb. I want to avoid script files and have everything in the step. I like the added security (however small) of needing SSMS privileges to view the code.
So, here are my questions:
1) Is there a way to elevate commands in a script block?
2) Is there a way to have the PowerShell step in an Agent Job run in Admin mode?
Extra credit question:
3) If I do need to add the Agent service account to a Windows User Group, which of the two dozen groups would give that account the minimum privileges needed to alter an ACL for a file, then eventually delete it?

Azure Powershell: What is the opposite command to Login-AzureRmAccount (used to be Clear-AzureProfile)

I have various scripts which I used to run in a wrapper to allow me to handle things like checking I had a valid connection and to ask the user if the connection/subscription currently selected is the one they want to run the script on before running it etc.
The classic commands have Clear-AzureProfile which allows me to run it from a script and effectively break the connection so that it can't be used again without calling Add-AzureAccount.
With the RM cmdlets I can only find Login-AzureRmAccount but once I've logged in...how do I call logout?
There doesn't appear to be a Logout-AzureRMAccount or Remove-AzureRMAccount and Clear-AzureProfile has no effect.
I run a dev workstation and connect to several different client subscriptions so want to be able to destroy the connection rather than just calling another login over the top of it (if that login failed I would still have the old connection set up which is dangerous for me)
I've just logged this at: https://msdn.microsoft.com/en-us/library/mt619248.aspx as from the documentation it looks like the commands may be lacking
It appears the following works:
Set-AzureRmContext -Context ([Microsoft.Azure.Commands.Profile.Models.PSAzureContext]::new())
UPDATE: For new powershell Azure "az" module, please use
Connect-AzAccount
for login and
Disconnect-AzAccount
for logout.
> get-command -Module AzureRM.Profile
CommandType Name
----------- ----
Alias Login-AzureRmAccount
Alias Select-AzureRmSubscription
Cmdlet Add-AzureRmAccount
Cmdlet Add-AzureRmEnvironment
Cmdlet Disable-AzureRmDataCollection
Cmdlet Enable-AzureRmDataCollection
Cmdlet Get-AzureRmContext
Cmdlet Get-AzureRmEnvironment
Cmdlet Get-AzureRmSubscription
Cmdlet Get-AzureRmTenant
Cmdlet Remove-AzureRmEnvironment
Cmdlet Save-AzureRmProfile
Cmdlet Select-AzureRmProfile
Cmdlet Set-AzureRmContext
Cmdlet Set-AzureRmEnvironment
Note that Login-AzureRmAccount is an alias to Add-AzureRmAccount and there's no corresponding Remove.
Set-AzureRmContext might take a $null to clear the context, but I would be surprised if it doesn't instead just give an error.
Directly closing your PS session would do. The AzureRM.Profile module won't persist your profile until you tell it to do so with Save-AzureRmProfile.
In latest powershell version 1.0.1 MS hasn't provided any cmdlets which you are searching like Logout-AzureRMAccount or Remove-AzureRMAccount and Clear-AzureRMProfile.
In your case I would rather suggest a workaround for you.
Firstly close your PS window, delete your cahce and temp data.
Secondly, Delete your name from Azure AD and then Add it back. Download a new publishsetting file and start doing afresh. Once you re-add the name it will treat everything as new for you.
It's worth noting that you can always kick out an exception if the call to Login-AzureRmAccount fails to ensure your script doesn't continue with the old account:
Login-AzureRmAccount -ErrorAction Stop
The resulting dialog won't allow an invalid login. It will let you know if you're already logged in and give the choice to stay logged in with the current account or login with another, at which point the user still has to make some sort of conscious choice to proceed. If they choose to cancel out of the login dialog, the resulting exception will stop the script.
login-azurermaccount : authentication_canceled: User canceled authentication
At line:1 char:1
+ login-azurermaccount
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Add-AzureRmAccount], AadAuthenticationCanceledException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.AddAzureRMAccountCommand
I know this is an old question. But it looks like this has been updated with Remove-AzureAccount. You can read more about it here and Remove-AzureRMAccount found here.
AzureRM context used to be bound to a powershell session, so just closing the console was enough.
But it seems latest versions of the powershell module have changed that.
Using the latest version of the powershell module, if you login in one console, you will also be logged in all the other consoles.
And you can log off using the new cmdlet Logout-AzureRmAccount.