How to iterate through each disk associated with Azure VM and get the encryption status using PowerShell? - azure-powershell

I want to first get the list of disks associated with a VM and then iterate through each disk properties to identify if the disk is Customer Managed Key(CMK) encrypted or not. How to perform this check using Azure PowerShell?

Generally, To get the encryption status of the virtual machine, you can use the Get-AzVMDiskEncryptionStatus cmdlet with the following syntax:
Get-AzVmDiskEncryptionStatus -ResourceGroupName $resourceGroupName -VMName $vmName
You will see the encryption status of the operating system and the data volumes.
If the above OsVolumeEncrypted or DataVolumesEncrypted displayed Encrypted, you probably have osDisk or dataDisk encrypted with CMK.
You also could capture the encryption settings from each disk by using the following PowerShell commands. For more details, you could read this article.
RGNAME="RGNAME"
VMNAME="VNAME"
$VM = Get-AzVM -Name $VMNAME -ResourceGroupName $RGNAME
$Sourcedisk = Get-AzDisk -ResourceGroupName $RGNAME -DiskName $VM.StorageProfile.OsDisk.Name
Write-Host "============================================================================================================================================================="
Write-Host " OS disk Encryption Settings:"
Write-Host "============================================================================================================================================================="
Write-Host "Enabled:" $Sourcedisk.EncryptionSettingsCollection.Enabled
Write-Host "Version:" $Sourcedisk.EncryptionSettingsCollection.EncryptionSettingsVersion
Write-Host "Source Vault:" $Sourcedisk.EncryptionSettingsCollection.EncryptionSettings.DiskEncryptionKey.SourceVault.Id
Write-Host "Secret URL:" $Sourcedisk.EncryptionSettingsCollection.EncryptionSettings.DiskEncryptionKey.SecretUrl
Write-Host "Key URL:" $Sourcedisk.EncryptionSettingsCollection.EncryptionSettings.KeyEncryptionKey.KeyUrl
Write-Host "============================================================================================================================================================="
foreach ($i in $VM.StorageProfile.DataDisks| ForEach-Object{$_.Name})
{
Write-Host "============================================================================================================================================================="
Write-Host "Data Disk Encryption Settings:"
Write-Host "============================================================================================================================================================="
Write-Host "Checking Disk:" $i
$Sourcedisk=(Get-AzDisk -ResourceGroupName $RGNAME -DiskName $i)
Write-Host "Encryption Enable: " $Sourcedisk.EncryptionSettingsCollection.Enabled
Write-Host "Encryption KeyEncryptionKey: " $Sourcedisk.EncryptionSettingsCollection.EncryptionSettings.KeyEncryptionKey.KeyUrl;
Write-Host "Encryption DiskEncryptionKey: " $Sourcedisk.EncryptionSettingsCollection.EncryptionSettings.DiskEncryptionKey.SecretUrl;
Write-Host "============================================================================================================================================================="
}

Related

How to enable auto scaling for SQL app in Azure Portal

I am looking to allow auto-scaling from my SQL DB app in Azure portal so that allow it to increase to 200 DTUs on a particular day and then automatically scale back down to 20. I seem to be getting confused as to how to go about it as I'm aware I will need to use Azure cli also. Any help would be much appreciated.
If you wanna scale SQL in Azure on some schedule I would recommend you to prepare Automation service with PowerShell script and schedules connected to that Runbook. Also you would need to configure Run as options.
I personally use this script to scale DB up and down on daily base.
## Authentication
Write-Output ""
Write-Output "------------------------ Authentication ------------------------"
Write-Output "Logging into Azure ..."
$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
}
}
##DB Part
$vCores = 18
$currentTier = "GP_Gen5"
$size = 200
$resourceGroup = ""
$serverName = ""
$databaseName = ""
$db_size = "GP_Gen5_4"
Write-Output "Changing DB type to GP_Gen5_4"
Set-AzureRmSqlDatabase `
-ServerName $serverName `
-ResourceGroupName $resourceGroup `
-DatabaseName $databaseName `
-RequestedServiceObjectiveName $db_size
# -RequestedServiceObjectiveName "$currentTier" + "_" + "$vCores"
Write-Output "Writing current DB parameters"
Get-AzureRmSqlDatabase `
-ServerName $serverName `
-ResourceGroupName $resourceGroup `
-DatabaseName $databaseName

Get All blob names from Storage account from Runbook

I have a very simple script which absolutely works fine when run from remote powershell ISE (not using the RUNAS credentials from the Automation Runbook), but when we try to run it from Automation Runbook it returns 0 . Following is the code:-
$connectionName = "AzureRunAsConnection"
$SubId = "XXXXXXXXXXXXXXXXXX"
try
{
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
Write-Verbose "Logging in to Azure..." -Verbose
Connect-AzAccount -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint -ApplicationId $servicePrincipalConnection.ApplicationId -Tenant $servicePrincipalConnection.TenantId -ServicePrincipal
Write-Verbose "Setting Subscription......" -Verbose
Set-AzContext -SubscriptionId $SubId | Write-Verbose
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccountName -ErrorAction SilentlyContinue
# Resource group name for the storage acccount
$ResourceGroup = "MYDEV01-RG"
# Storage account name
$StorageAccountName = "myDev01StrgName"
# Container name for analytics logs
$ContainerName = "`$logs"
$storageContext = $storageAccount.Context
$containers = New-Object System.Collections.ArrayList
$container = Get-AzStorageContainer -Context $storageContext -Name $ContainerName -ErrorAction SilentlyContinue |
ForEach-Object { $containers.Add($_) } | Out-Null
Write-Output("> Container count: {0}" -f $containers.Count)
Not sure if we are missing something like permissions or some other thing because of with the Automation Account (Runbook) is not working, any help?
Thank you,
After spending 24 hours on this one and staring and trying everything, it turned out that the ABOVE SCRIPT is correct and nothing is wrong in it but the STORAGE ACCOUNT's FIREWALL and NETWORK Setting were set to SELECTED NETWORK (You can either add the network IP addresses which you want to permit or select All Networks and that helped me resolve my issue). In NO WAYS I am suggesting SELECTING ALL NETWORKS but for testing we can and then add only the Selected networks and that should work.

Create point-to-site connection for all web apps slots using powershell

I'm following the tutorial from here https://azure.microsoft.com/pl-pl/documentation/articles/app-service-vnet-integration-powershell/
where I've a script which allows me to connect multiple web apps with VNet.
The issue is our web apps have few deployment slots and when this script is run it only updates currently used slot.
I wasn't able to get web app from different slot by the name, also I don't see any parameter which would apply my configuration to all slots.
Script for the reference:
function ConnectWebAppWithVNet()
{
param(
$SubscriptionId,
$VNetResourceGroupName,
$AppResourceGroupName,
$WebAppName,
$VNetName,
$GatewayName,
$P2SRootCertName2,
$MyP2SCertPubKeyBase64_2
)
$webApp = Get-AzureRmResource -ResourceName $WebAppName -ResourceType "Microsoft.Web/sites" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName
$location = $webApp.Location
$vnet = Get-AzureRmVirtualNetwork -name $VNetName -ResourceGroupName $VNetResourceGroupName
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $GatewayName
# validate gateway types, etc.
if($gateway.GatewayType -ne "Vpn")
{
Write-Error "This gateway is not of the Vpn type. It cannot be joined to an App."
return
}
if($gateway.VpnType -ne "RouteBased")
{
Write-Error "This gateways Vpn type is not RouteBased. It cannot be joined to an App."
return
}
if($gateway.VpnClientConfiguration -eq $null -or $gateway.VpnClientConfiguration.VpnClientAddressPool -eq $null)
{
Write-Host "This gateway does not have a Point-to-site Address Range. Please specify one in CIDR notation, e.g. 10.0.0.0/8"
return
}
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $propertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName -Force
# We need to check if the certificate here exists in the gateway.
$certificates = $gateway.VpnClientConfiguration.VpnClientRootCertificates
$certFound = $false
foreach($certificate in $certificates)
{
if($certificate.PublicCertData -eq $virtualNetwork.Properties.CertBlob)
{
$certFound = $true
break
}
}
if(-not $certFound)
{
Write-Host "Adding certificate"
Add-AzureRmVpnClientRootCertificate -ResourceGroupName $VNetResourceGroupName -VpnClientRootCertificateName "AppServiceCertificate.cer" -PublicCertData $virtualNetwork.Properties.CertBlob -VirtualNetworkGatewayName $gateway.Name
}
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri
}
New-AzureRmResource -Location $location -Properties $propertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName -Force
Write-Host "Finished!"
}
If your web app is already connected to VPN there is a way to connect also its slot.
$webAppName = "name_of_app_service"
$resourceGroup = "name_of_resource_group"
$vnetName = "name_of_vnet"
$slotName = "staging"
$resName = $webAppName + "/" + $slotName
$WebAppConfig = Get-AzureRmResource -ResourceGroupName $resourceGroup -ResourceType Microsoft.Web/sites/slots/config -ResourceName $resName -ApiVersion 2016-08-01
$WebAppConfig.Properties.vnetName = $vnetName
Set-AzureRmResource -ResourceId $WebAppConfig.ResourceId -Properties $WebAppConfig.Properties -ApiVersion 2016-08-01 # -Force
I've manged to get help from Azure support and we've found out the problem:
I've created secondary slot without cloning the configuration
settings from main slot. If this setting would be selected,
secondary slot would be connected automatically. In my case I couldn't recreate slot so I needed to manually
connect secondary slot after swapping.

Authentication in Powershell to windows server 2012 PKI

I made a script in powershell to make a .REQ from a .INF file. This file (the .REQ) must then be imported into the PKI, which then generates a .CERT.
My problem is that I do not know how to authenticate myself to the PKI from Powershell. Second question if I may ask, how do I choose the certificate Template (in the PKI online screen, I have a choice box in which I choose my template (for eg Wifi client").
Here is my code so far, of course I don't know how to authenticate, that is my main question here. I precise that I know the login and the password (I successfully connect myself using RDP).
# Generate Request File .req
Write-Host " This script generates a .REQ (step 1/3 in certificate creation)"
Write-Host " "
Write-Host " Step 1/3: create .INF file with Key length and other parameters, create a .REQ file"
Write-Host " Step 2/3: import the .REQ file into the Intermediate PKI and generate a .CER"
Write-Host " Step 3/3: from the .CER file, create a .PFX with the exportable key"
# Variables declaration
#
# UID = nom du PDA ou son numero de serie
# $Login = login sur la PKI intermediate
# $Pass = Password sur la PKI intermediate
$Date = (Get-Date).ToString('ddMMyyyy')
Write-Host " "
[string]$UID = read-host "Please enter the Device Name (or Serial Number)"
$Path = "C:\users\youcef\Desktop\Julie\"
$Login = "me"
$Pass = "pass"
# INF File content
$ReqFile = "$UID" + "_" + "$Date" + ".req"
$InfFile = #"
[NewRequest]`r
Subject = "CN=$UID"`r
KeySpec = 1
Exportable = TRUE
RequestType = PKCS10
[PolicyStatementExtension]
Policies=InternalPolicy
[InternalPolicy]
OID= 1.2.3.4.1455.67.89.5
Notice="Legal Policy Statement
[Certsrv_Server]
RenewalKeyLength=1024
RenewalValidityPeriod=Years
RenewalValidityPeriodUnits=2
CRLPeriod=weeks
CRLPeriodUnits=52
CRLDeltaPeriod=Days
CRLDeltaPeriodUnits=0
LoadDefaultTemplates=1
AlternateSignatureAlgorithm=0
"#
# Generate Request File from INF File
Write-Host "Generating Certificate Request file..." -ForegroundColor Yellow;
$MYCERTNAME = "$UID" + "_" + "$Date" + ".inf"
New-Item $MYCERTNAME -type file -value $InfFile
certreq -new $path\$MYCERTNAME $path\$ReqFile
Write-Host " "
Write-Host "Certificate request file for $UID successfully generated!" -foregroundcolor DarkGreen;
# Authentication on PKI: HERE I AM TOTALLY LOST
Connect-CertificationAuthority -ComputerName ca01.company.com
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $Login, $Pass
$serverNameOrIp = "192.168.1.1"
Restart-Computer -ComputerName $serverNameOrIp `
-Authentication default `
-Credential $cred
<any other parameters relevant to you>
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
$serverNameOrIp = "https://pki.mycompany.fr/certsrv/certrqxt.asp"
Restart-Computer -ComputerName $serverNameOrIp `
-Authentication default `
-Credential $cred
<any other parameters relevant to you>
certreq -submit -config "https://pki.mycompany.fr/certsrv/certrqxt.asp" $path\$ReqFile $path\$UID.cer
#certreq -submit -config "https://pki.mycompany.fr\certsrv" $path\$ReqFile $path\$UID.cer
certreq -accept $path\$UID.cer
certutil -exportpfx -p "Welcome123" MY $UID $path\clientcerts\$UID.pfx
I solved my issue in launching my script directly on the server.
Not the best solution, but I neevr managed to use Remote Session in Powershell

Azure database backup to blob using Powershell

We need to backup the azure database and store it on blob so that it can be restored. I've seen this blog but it uses the third party cmdlets.
http://weblogs.thinktecture.com/cweyer/2011/01/automating-backup-of-a-sql-azure-database-to-azure-blob-storage-with-the-help-of-powershell-and-task-scheduler.html
Could someone please guide/help how above can be achieved using powershell.
Backing up to WA Blob Store is not supported from Azure DB, rather the service does automatic backups for you with PITR capability. You'll find the following documentation useful:
http://msdn.microsoft.com/en-us/library/azure/hh852669.aspx
http://msdn.microsoft.com/en-us/library/azure/jj650016.aspx
Hope this helps.
Here is my powershell script
https://gist.github.com/voxon2/be29a3fd6dabbb9155ca
Here is an article describing many different approaches other than powershell
http://blogs.msdn.com/b/mast/archive/2013/03/04/different-ways-to-backup-your-windows-azure-sql-database.aspx
First get your Azure Automation Settings done (see here).
Edit the blow script and save it as .ps1 file. When you run it for
the first time, it will ask you both your azure automation account and
your database credentials. During this process, it will save your
credentials in a local file securely (see here how it is done). After this time on wards, it uses the saved credentials.
The .psl file and the encrypted credential files should be stored in one
directory
Once you are happy you can schedule it to run in task scheduler.
function Get-MyCredential
{
param(
$CredPath,
[switch]$Help
)
$HelpText = #"
Get-MyCredential
Usage:
Get-MyCredential -CredPath `$CredPath
If a credential is stored in $CredPath, it will be used.
If no credential is found, Export-Credential will start and offer to
Store a credential at the location specified.
"#
if($Help -or (!($CredPath))){write-host $Helptext; Break}
if (!(Test-Path -Path $CredPath -PathType Leaf)) {
Export-Credential (Get-Credential) $CredPath
}
$cred = Import-Clixml $CredPath
$cred.Password = $cred.Password | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password)
Return $Credential
}
function Export-Credential($cred, $path) {
$cred = $cred | Select-Object *
$cred.password = $cred.Password | ConvertFrom-SecureString
$cred | Export-Clixml $path
}
#Create a directory with you azure server name to isolate configurations
$FileRootPath = "C:\PowerShellScripts\AzureServerName"
Write-Host "Getting Azure credentials"
$AzureCred = Get-MyCredential ($FileRootPath + "AzureSyncred.txt")
#Use Azure Automation Account
#(If You do not have it will not work with other accounts)
Add-AzureAccount -Credential $AzureCred
Select-AzureSubscription -SubscriptionId "myAzureSubscriptionId"
#DO NOT use tcp:myServerName.database.windows.net,1433 but only myServerName
$ServerName = "myServerName"
$Date = Get-Date -format "yyyy-MM-dd-HH-mm"
$DatabaseName = "myTargetDatabaseName"
$BlobName = $Date + "-" + $DatabaseName.bacpac"
$StorageName = "myStorageAccountName"
$ContainerName = "myContainerNameToStoreBacpacFiles"
$StorageKey = "myStorageAccountKey"
Write-Host "Getting database user credential"
#DO NOT use myDatabaseUsername#myServerName but only myDatabaseUsername
$credential = Get-MyCredential ($FileRootPath + "DbSyncred.xml")
Write-Host "Connecting to Azure database"
$SqlCtx = New-AzureSqlDatabaseServerContext -ServerName $ServerName -Credential $credential
Write-Host "Connecting to Blob storage"
$StorageCtx = New-AzureStorageContext -StorageAccountName $StorageName -StorageAccountKey $StorageKey
$Container = Get-AzureStorageContainer -Name $ContainerName -Context $StorageCtx
Write-Host "Exporting data to blob"
$exportRequest = Start-AzureSqlDatabaseExport -SqlConnectionContext $SqlCtx -StorageContainer $Container -DatabaseName $DatabaseName -BlobName $BlobName
Get-AzureSqlDatabaseImportExportStatus -Request $exportRequest
# use the below script in powershell to execute the script
# powershell -ExecutionPolicy ByPass –File C:\PowerShellScripts\AzureServerName\mySavedScript.ps1 –noexit