├── LICENSE ├── README.md └── Scripts ├── ASR Pre-Requisites ├── Check-ASRPrerequisiteServices.ps1 └── Set-ASRPrerequisiteServivces.ps1 ├── Apply-LocksOnVariousAzureResources └── Apply-LocksOnVariousAzureResources.ps1 ├── Apply-RBACRoleToResources ├── Apply-RBACRoleToResources.ps1 └── Input-AzureVMsList.csv ├── Azure Automation - ASR Recovery Plan ├── ASR-Get-VMSInfoFromASRContext.ps1 ├── ASR-RunbookForRecoveryPlans.ps1 └── RecoveryPlanContext Sample.txt ├── Azure Automation - Check VM Availability └── Check-VMAvailability.ps1 ├── Azure Automation - Get VM Information From Azure └── Get-VMInfoFromAzure.ps1 ├── Azure Automation - Send Email Notification └── Send-EmailNotificationFromAzureAutomationRunbook.ps1 ├── Azure VM Operations ├── Apply-HubLicensing - Config.csv ├── Apply-HubLicensing.ps1 ├── Change-AzureVMSize - Config.csv ├── Change-AzureVMSize.ps1 ├── Convert-VMToManagedDisk - Config.csv ├── Convert-VMToManagedDisk.ps1 ├── Enable-VMBackup - Config.csv ├── Enable-VMBackup.ps1 ├── Export-VMConfig - Config.csv └── Export-VMConfig.ps1 ├── Create-ResourceGroupsWithRBACAssignments └── Create-ResourceGroupsWithRBACAssignments.ps1 ├── Enable-RHELBYOSLicense └── Enable-RHELBYOSLicense.ps1 ├── Enable-SUSEBYOSLicense └── Enable-SUSEBYOSLicense.ps1 ├── Enable-WindowsAdminCenter └── Enable-WindowsAdminCenter.ps1 ├── Export-AllAutomationRunbooksAndVariables └── Export-AllAutomationRunbooksAndVariables.ps1 ├── Export-AllAzureCustomPolicies └── Export-AllAzureCustomPolicies.ps1 ├── Export-OMSLogAnalyticsSavedSearches └── Export-OMSLogAnalyticsSavedSearches.ps1 ├── Format-EABillingUsageCsvForTags ├── Format-EABillingUsageCsvForTags.ps1 ├── Input Sample - EA Azure Billing CSV.csv └── Output - UsageWithTags-2019-03-03-06-26.csv ├── Get-AzResourceInfo-VMsAndAllRelatedDisks ├── Get-AzResourceInfo-VMsAndAllRelatedDisks.ps1 ├── SAMPLE OUTPUT - ResourceReportVMAndDisks.csv └── SAMPLE REPORT - ResourceReportVMAndDisks.xlsx ├── Get-AzureRmResourceReport ├── Get-AzureRmAllResourceReport.ps1 └── Get-AzureRmResourceReportForOneResourceGroup.ps1 ├── Get-AzureRmTagsReport.ps1 ├── Get-AzureSQLDatabases └── Get-AzureSQLDatabases.ps1 ├── Get-IsElevated └── Get-IsElevated.ps1 ├── Get-PendingReboot └── Get-PendingReboot.ps1 ├── Get-SSPSync └── SSPSyncProcess.ps1 ├── Get-SubnetsReport ├── Get-SubnetsReport01.ps1 └── Subnet Reports script details.md ├── Get-VMRunning └── VMRunning24hrs.ps1 ├── Install-SAPMonitoringExtensionInLoop └── Install-SAPMonitoringExtensionInLoop.ps1 ├── Move-AzVMToAvailabilityZone └── Move-AzVMToAvailabilityZone.ps1 ├── Remove-Locks └── Remove-Locks.ps1 ├── Request-Rest.ps1 ├── Request-RestPost.ps1 ├── StorageAccountBlobManagement.ps1 ├── Tagging Reports ├── Get-AzureRmTagsReport - v3.0.ps1 └── Set-AzureRmTags.ps1 ├── Test-NetworkWatcherRouteNextHop ├── Input-EnvironmentDetails-ForAutomation.csv └── Test-NetworkWatcherRouteNextHop.ps1 ├── Trigger-AzSAPHANAOnDemandBackup ├── Trigger-AzSAPHANAOnDemandBackup.ps1 └── VMNames - SAP HANA DBs - Input.csv ├── Trigger-AzVMOnDemandBackup ├── Trigger-AzVMOnDemandBackup.ps1 └── VMNames - Input - Sample.csv ├── Update-CustomRoleSample └── Update-CustomRoleSample.ps1 ├── User Defined Routes (UDRs) or Route Tables Related Scripts ├── Associate-SubnetsToUDRs - input.csv ├── Associate-SubnetsToUDRs.ps1 ├── Disassociate-SubnetsFromUDRs.ps1 └── Report-UDRsWithSubnetInfo.ps1 └── Working with Azure VM Snapshots ├── Copy-SnapshotToStorage.ps1 └── Create-VMFromSnapshot.ps1 /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Aman Sharma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerShell Script Samples to automate various Azure related scenarios 2 | 3 | Collection of various PowerShell **reusable** functions and scripts. 4 | 5 | These samples are documented here: Azure Script Samples - Series Index 6 | 7 | The direct links to the related blog posts are: 8 | 9 | 10 | 1. Format EA Billing Usage Csv for Tags 11 | 2. Export All Azure Automation Account Runbooks and Variables 12 | 3. Export All OMS Log Analytics Saved Searches 13 | 4. Check Azure Site Recovery (ASR) Prerequisite Services 14 | 5. Set Azure Site Recovery (ASR) Prerequisite Services 15 | 6. Updating a Custom RBAC Role in Azure 16 | 7. Azure Automation - Runbook for ASR Recovery Plan 17 | 8. Azure Automation - Get VM Information from ASR Recovery Plan Context 18 | 9. Azure Automation - Sending Email Notification 19 | 10. Azure Automation - Get VM Information from actual Azure Virtual Machine 20 | 11. Azure Automation - Check VM Availability 21 | 12. Apply Locks on Various Azure Resources 22 | 13. Check for Pending Reboots on various VMs in your environment 23 | 14. Apply RBAC Role to Users on Resources 24 | 15. Getting Azure Resource Reports 25 | 16. Generate Azure Resources Report by Tags v3.0 26 | 17. Set Tags on Azure Resources 27 | 18. Creating Multiple Resource Groups with RBAC Role Assignment 28 | 19. Checking if the Prompt for current script is Elevated or not 29 | 20. VM Operations - Setting up the VM Backup 30 | 21. VM Operations - Convert VM to Managed Disk VM 31 | 22. VM Operations - Change Azure VM Size 32 | 23. VM Operations - Apply HUB Licensing to Existing VMs 33 | 24. VM Operations - Export VM Configurations 34 | 25. VM Operations - Working with VM Snapshots and moving the Managed VMs across subscriptions and regions 35 | 26. Removing Locks from Azure Resources 36 | 27. Generate Report for Route Tables with associated Subnets and related information 37 | 28. Disassociate and Associate Subnets to Route Tables 38 | 29 Get Subnets Report 39 | 30. Getting a report for all VMs and it's related OS and Data Disks 40 | 31. Automate Azure Route Table testing using Network Watcher and PowerShell scripting 41 | 32. Automatically trigger on-demand Azure VM Backup for multiple VMs 42 | 33. Automatically trigger on-demand SAP HANA on Azure VM Backup for multiple Databases 43 | 34. Moving an Azure Virtual Machine (VM) to an Availability Zone the automated way 44 | 35. Export all custom Azure Policies 45 | 36. Automating the enabling of BYOS licensing for all Red Hat Enterprise Linux (RHEL) VMs in Azure 46 | 37. Automating the enabling of BYOS licensing for all SUSE VMs in Azure 47 | 38. Automate locking of all resources of a particular type 48 | 39. Installing Enhanced Monitoring Agent for Multiple SAP workloads in Azure 49 | -------------------------------------------------------------------------------- /Scripts/ASR Pre-Requisites/Check-ASRPrerequisiteServices.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | 4 | This will query the remote computers and check for service status for the 3 ASR Required services, and export to CSV 5 | 6 | .EXAMPLE 7 | PS $ComputerName = Get-Content C:\Users\svc_azure_siterecovp\Downloads\servers.txt 8 | PS C:\>.\Check-ASRPrerequisiteServivces.ps1 | Export-Csv C:\Users\svc_azure_siterecovp\Downloads\CheckServicesReport.csv -NoTypeInformation 9 | 10 | #> 11 | 12 | foreach ($computer in $ComputerName) { 13 | 14 | $servicesToCheck = "MSDTC","VSS", "COMSysApp" 15 | 16 | $services = Get-Service -ComputerName $computer | Select Name, Status, StartType 17 | $IP_Config = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName $computer 18 | $IP_Result = $IP_Config.DhcpEnabled 19 | 20 | $IP_Output = if ($IP_Result -eq 'True' ) { 21 | 22 | $IP_Props = @{ServerName=$computer; 23 | Result="IP Set Incorectly" 24 | } 25 | New-Object -TypeName PSObject -Property $IP_Props 26 | } 27 | Else { 28 | $IP_Output = 29 | $IP_Props = @{ServerName=$computer; 30 | Result="IP Set Correctly" 31 | } 32 | New-Object -TypeName PSObject -Property $IP_Props 33 | } 34 | 35 | $results = foreach ($service in $servicesToCheck) { 36 | 37 | 38 | $checkService = $services | Where{ $_.Name -eq $service} 39 | 40 | if (($checkService.status -eq 'running' ) -and ($checkservice.StartType -eq 'automatic')) { 41 | 42 | 43 | $props = @{ServerName=$computer; 44 | Result="Set Correctly"; 45 | Service_Name=$service 46 | 47 | } 48 | New-Object -TypeName PSObject -Property $props 49 | } 50 | else { 51 | 52 | $props = @{ServerName=$computer; 53 | Result="Set Incorectly"; 54 | Service_Name=$service 55 | } 56 | New-Object -TypeName PSObject -Property $props 57 | } 58 | } 59 | 60 | $results 61 | $IP_Output 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Scripts/ASR Pre-Requisites/Set-ASRPrerequisiteServivces.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | 4 | This will query the remote computers and check for service status for the 3 ASR Required services, and export to CSV 5 | 6 | .EXAMPLE 7 | PS $ComputerName = Get-Content C:\Users\svc_azure_siterecovp\Downloads\servers.txt 8 | PS C:\>.\set-Servivces.ps1 | Export-Csv C:\Users\svc_azure_siterecovp\Downloads\SetServicesReport.csv -NoTypeInformation 9 | 10 | #> 11 | 12 | foreach ($computer in $ComputerName) { 13 | 14 | $servicesToCheck = "MSDTC","VSS","COMSysApp" 15 | 16 | $services = Get-Service -ComputerName $computer | Select Name, Status, StartType 17 | 18 | $results = foreach ($service in $servicesToCheck) { 19 | 20 | $checkService = $services | Where{ $_.Name -eq $service} 21 | 22 | if (($checkService.status -eq 'running' ) -and ($checkservice.StartType -eq 'automatic')) { 23 | 24 | $props = @{ServerName=$computer; 25 | Result="Set Correctly"; 26 | Service_Name=$service 27 | } 28 | New-Object -TypeName PSObject -Property $props 29 | } 30 | else{ 31 | $service1 = Get-Service -Name 'msdtc' -ComputerName $computer 32 | $service2 = Get-Service -Name 'VSS' -ComputerName $computer 33 | $service3 = Get-Service -Name 'COMSysApp' -ComputerName $computer 34 | if (($Service1.status -eq 'running' ) -and ($service1.StartType -eq 'automatic')){ 35 | } 36 | else { 37 | Set-Service -name 'msdtc' -ComputerName $Computer -StartupType Automatic 38 | Start-Sleep -s 5 39 | Get-Service -Name 'msdtc' -ComputerName $computer| Start-Service 40 | 41 | } 42 | if (($Service2.status -eq 'running' ) -and ($service2.StartType -eq 'automatic')){ 43 | } 44 | else { 45 | Set-Service -name 'VSS' -ComputerName $Computer -StartupType Automatic 46 | Start-Sleep -s 5 47 | Get-Service -Name 'VSS' -ComputerName $computer| Start-Service 48 | } 49 | if (($Service3.status -eq 'running' ) -and ($service3.StartType -eq 'automatic')){ 50 | } 51 | else { 52 | Set-Service -name 'COMSysApp' -ComputerName $Computer -StartupType Automatic 53 | Start-Sleep -s 5 54 | Get-Service -Name 'COMSysApp' -ComputerName $computer| Start-Service 55 | } 56 | 57 | $props = @{ServerName=$computer; 58 | Result="Service Now Set Correctly"; 59 | Service_Name=$service 60 | } 61 | New-Object -TypeName PSObject -Property $props 62 | } 63 | } 64 | 65 | $results 66 | } 67 | 68 | -------------------------------------------------------------------------------- /Scripts/Apply-LocksOnVariousAzureResources/Apply-LocksOnVariousAzureResources.ps1: -------------------------------------------------------------------------------- 1 | Add-AzureRmAccount 2 | 3 | $subs = Get-AzureRmSubscription 4 | 5 | foreach($sub in $subs) 6 | { 7 | Select-AzureRmSubscription -SubscriptionName $sub.SubscriptionName 8 | 9 | # 1. Virtual Networks 10 | $vNets = Get-AzureRmVirtualNetwork 11 | 12 | foreach($vNet in $vNets) 13 | { 14 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $vNet.Name -ResourceType $vNet.Type -ResourceGroupName $vNet.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 15 | } 16 | 17 | # 2. Route Tables 18 | $routes = Get-AzureRmRouteTable 19 | 20 | foreach($route in $routes) 21 | { 22 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $route.Name -ResourceType $route.Type -ResourceGroupName $route.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 23 | } 24 | 25 | # 3. Express Routes 26 | $expressRoutes = Get-AzureRmExpressRouteCircuit 27 | 28 | foreach($expressRoute in $expressRoutes) 29 | { 30 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $expressRoute.Name -ResourceType $expressRoute.Type -ResourceGroupName $expressRoute.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 31 | } 32 | 33 | #region 4. Virtual network Gateway 34 | $gateway = $null 35 | $rgName = "RG-Test-USE2" 36 | if((Get-AzureRmResourceGroup -Name $rgName -ErrorAction Ignore) -ne $null) 37 | { 38 | $gateways = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $rgName 39 | 40 | foreach($gateway in $gateways) 41 | { 42 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $gateway.Name -ResourceType $gateway.Type -ResourceGroupName $gateway.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 43 | } 44 | } 45 | $gateway = $null 46 | $rgName = "RG-Test-USNC" 47 | if((Get-AzureRmResourceGroup -Name $rgName -ErrorAction Ignore) -ne $null) 48 | { 49 | $gateways = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $rgName 50 | 51 | foreach($gateway in $gateways) 52 | { 53 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $gateway.Name -ResourceType $gateway.Type -ResourceGroupName $gateway.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 54 | } 55 | } 56 | #endregion 57 | 58 | #region 5. Virtual Network Gateway Connections 59 | # 5.1 USE Region 60 | $gateway = $null 61 | $rgName = "RG-Test-USE" 62 | if((Get-AzureRmResourceGroup -Name $rgName -ErrorAction Ignore) -ne $null) 63 | { 64 | $gatewayConnections = Get-AzureRmVirtualNetworkGatewayConnection -ResourceGroupName $rgName 65 | 66 | foreach($gatewayConnection in $gatewayConnections) 67 | { 68 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $gatewayConnection.Name -ResourceType $gatewayConnection.Type -ResourceGroupName $gatewayConnection.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 69 | } 70 | } 71 | 72 | # 5.2 USNC region 73 | $gateway = $null 74 | $rgName = "RG-Test-USNC" 75 | if((Get-AzureRmResourceGroup -Name $rgName -ErrorAction Ignore) -ne $null) 76 | { 77 | $gatewayConnections = Get-AzureRmVirtualNetworkGatewayConnection -ResourceGroupName $rgName 78 | 79 | foreach($gatewayConnection in $gatewayConnections) 80 | { 81 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $gatewayConnection.Name -ResourceType $gatewayConnection.Type -ResourceGroupName $gatewayConnection.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 82 | } 83 | } 84 | #endregion 85 | 86 | 87 | # 6. Recovery Services Vaults (ASR Vaults) 88 | $vaults = Get-AzureRmRecoveryServicesVault 89 | 90 | foreach($vault in $vaults) 91 | { 92 | New-AzureRmResourceLock -LockLevel CanNotDelete -LockName DoNotDelete -ResourceName $vault.Name -ResourceType $vault.Type -ResourceGroupName $vault.ResourceGroupName -LockNotes "Do Not Delete Lock" -Confirm -Force 93 | } 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /Scripts/Apply-RBACRoleToResources/Apply-RBACRoleToResources.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | PowerShell script will grant role to users or groups at Subscription/ResourceGroup/VirtualMachine Level 4 | .DESCRIPTION 5 | PowerShell script will grant role to users or groups at Subscription/ResourceGroup/VirtualMachine Level 6 | .EXAMPLE 7 | Apply-RBACRoleToResources -csvLocation "C:\Users\aman\Documents\AzureVM.csv" -role "Virtual Machine Operator" -Scope "VirtualMachine" -UserNames "user1,user2" -GroupNames "abac" 8 | .EXAMPLE 9 | Apply-RBACRoleToResources -csvLocation "C:\Users\aman\Documents\AzureVM.csv" -role "Virtual Machine Operator" -Scope "ResourceGroup" -UserNames "user1,user2" -GroupNames "abac" 10 | .INPUTS 11 | CSVLocation, role, scope, usernames, groupnames, 12 | • csvLocation:- Path of the CSV File 13 | • Role:- Name of the role 14 | • Scope:- Grant access at Subscription\ResourceGroup\VirtualMachine Level 15 | • UserNames:- Give multiple user names separated by a comma 16 | • GroupNames:- Give multiple groups separated by a comma 17 | 18 | .OUTPUTS 19 | Output from this cmdlet (if any) 20 | .NOTES 21 | General notes 22 | .COMPONENT 23 | The component this cmdlet belongs to 24 | .ROLE 25 | The role this cmdlet belongs to 26 | .FUNCTIONALITY 27 | The functionality that best describes this cmdlet 28 | #> 29 | Function Apply-RBACRoleToResources 30 | { 31 | param 32 | ( 33 | [parameter(Mandatory = $true)] 34 | [String]$csvLocation, 35 | [parameter(Mandatory = $true)] 36 | [String]$role, 37 | [parameter(Mandatory = $false)] 38 | [ValidateSet("VirtualMachine", "Subscription", "ResourceGroup")] 39 | [String]$Scope, 40 | [parameter(Mandatory = $false)] 41 | [String]$UserNames, 42 | [parameter(Mandatory = $true)] 43 | [String]$GroupNames, 44 | [parameter(Mandatory = $false)] 45 | [boolean] $RBACVMOperatorFlag = $true 46 | ) 47 | 48 | if ($RBACVMOperatorFlag) 49 | { 50 | $UserFlag = $True 51 | $GroupFlag = $True 52 | $UserNamesArray = @() 53 | $GroupNamesArray = @() 54 | 55 | if ($UserNames -ne $null) 56 | { 57 | $UserNamesArray = $UserNames.Split(',') 58 | $UserFlag = $True 59 | } 60 | else 61 | { 62 | $UserFlag = $False 63 | } 64 | if ($GroupNames -ne $null) 65 | { 66 | $GroupNamesArray = $GroupNames.Split(',') 67 | $GroupFlag = $True 68 | } 69 | else 70 | { 71 | $GroupFlag = $False 72 | } 73 | if ($UserFlag -or $GroupFlag) 74 | { 75 | if (Test-Path -Path $csvLocation) 76 | { 77 | 78 | Write-Host "Importing CSV File" 79 | $csvImport = Import-Csv -Path $csvLocation 80 | } 81 | else { 82 | Write-Host "CSV FILE NOT FOUND!" 83 | Exit 84 | } 85 | 86 | $AzureLoginResults = Login-AzureRmAccount -ErrorAction SilentlyContinue -ErrorVariable LoginError 87 | Write-Host "Login to Azure" 88 | #Check for Login Errors 89 | if ($LoginError.Count -gt 0) 90 | { 91 | $ErrorDetail = $LoginError.Exception.Message; 92 | Write-Verbose "Login failed with Error: $ErrorDetails" 93 | $LoginStatus = "Failed" 94 | $RetunrObjItm = new-object PSObject 95 | $RetunrObjItm | add-member NoteProperty "VMName" -value $VMName 96 | $RetunrObjItm | add-member NoteProperty "RBAC Virtual Machine Operator Status" -value $LoginStatus 97 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 98 | 99 | } 100 | else 101 | { 102 | foreach ($csvItem in $csvImport) 103 | { 104 | $VMName = $csvItem.VM 105 | $VMResourceGroup = $csvItem.ResourceGroup 106 | #$SelectSub = Select-AzureRmSubscription -SubscriptionId $AzureLoginResults.SubscriptionId 107 | $AzureROleObj = Get-AzureRmRoleDefinition $role -ErrorAction SilentlyContinue -ErrorVariable AzureRoleDefError 108 | 109 | if ($AzureRoleDefError.Count -gt 0) 110 | { 111 | $ErrorDetails = $AzureRoleDefError[0].Exception.Message 112 | Write-Verbose "RBAC for $role failed with Error: $ErrorDetails" 113 | $RBACStatus = "Failed" 114 | $RetunrObjItm = new-object PSObject 115 | $RetunrObjItm | add-member NoteProperty "RBAC ROle" -value $role 116 | $RetunrObjItm | add-member NoteProperty "RBAC Status" -value $RBACStatus 117 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 118 | 119 | } 120 | else 121 | { 122 | if ($Scope -eq "Subscription") 123 | { 124 | $scope = "/subscriptions/" + $AzureLoginResults.SubscriptionId 125 | 126 | } 127 | elseif ($Scope -eq "ResourceGroup") 128 | { 129 | $scope = (Get-AzureRmResourceGroup -Name $VMResourceGroup).ResourceId 130 | } 131 | elseif ($Scope -eq "VirtualMachine") 132 | { 133 | 134 | $scope = (Get-AzureRmResource -ResourceGroupName $VMResourceGroup -ResourceName $VMName).ResourceId 135 | 136 | } 137 | if ($scope -ne $null) 138 | { 139 | $RetunrObjItm = new-object PSObject 140 | [int]$countUser = 0 141 | [int]$countGroup = 0 142 | foreach ($UserName in $UserNamesArray) 143 | { 144 | $countUser++ 145 | $ObjectID = (Get-AzureRmADUser -SearchString $UserName).Id 146 | $RBACObj = New-AzureRmRoleAssignment -ObjectId $ObjectID -Scope $scope -RoleDefinitionName $AzureROleObj.Name -ErrorAction SilentlyContinue -ErrorVariable RBACError 147 | if ($RBACError.Count -gt 0) 148 | { 149 | $ErrorDetails = $RBACError[0].Exception.Message 150 | Write-Verbose "RBAC for $UserName failed with Error: $ErrorDetails" 151 | $RBACStatus = "Failed" 152 | $RetunrObjItm | add-member NoteProperty "User Name$countUser" -value $UserName 153 | $RetunrObjItm | add-member NoteProperty "RBAC User Status$countUser" -value $RBACStatus 154 | $RetunrObjItm | add-member NoteProperty "ErrorDetails User$countUser" -value $ErrorDetails 155 | } 156 | else 157 | { 158 | Write-Verbose "RBAC for $UserName Succeed" 159 | $RBACStatus = "Succeed" 160 | $RetunrObjItm | add-member NoteProperty "User Name$countUser" -value $UserName 161 | $RetunrObjItm | add-member NoteProperty "RBAC User Status$countUser" -value $RBACStatus 162 | } 163 | } 164 | foreach ($GroupName in $GroupNamesArray) 165 | { 166 | $countGroup++ 167 | $ObjectID = (Get-AzureRmADGroup -SearchString $GroupName).Id 168 | $RBACObj = New-AzureRmRoleAssignment -ObjectId $ObjectID -Scope $scope -RoleDefinitionName $AzureROleObj -ErrorAction SilentlyContinue -ErrorVariable RBACError 169 | if ($RBACError.Count -gt 0) 170 | { 171 | $ErrorDetails = $RBACError[0].Exception.Message 172 | Write-Verbose "RBAC for $GroupName failed with Error: $ErrorDetails" 173 | $RBACStatus = "Failed" 174 | $RetunrObjItm | add-member NoteProperty "Group Name$countGroup" -value $GroupName 175 | $RetunrObjItm | add-member NoteProperty "RBAC Group Status$countGroup" -value $RBACStatus 176 | $RetunrObjItm | add-member NoteProperty "ErrorDetails Group$countGroup" -value $ErrorDetails 177 | } 178 | else 179 | { 180 | Write-Verbose "RBAC for $GroupName Succeed" 181 | $RBACStatus = "Succeed" 182 | $RetunrObjItm | add-member NoteProperty "Group Name$countGroup" -value $GroupName 183 | $RetunrObjItm | add-member NoteProperty "RBAC Group Status$countGroup" -value $RBACStatus 184 | } 185 | } 186 | } 187 | else 188 | { 189 | $ErrorDetails = "RBAC for role failed with Error: Unable to retreive Scope ResourceID" 190 | Write-Verbose $ErrorDetails 191 | $RBACStatus = "Failed" 192 | $RetunrObjItm = new-object PSObject 193 | $RetunrObjItm | add-member NoteProperty "RBAC ROle" -value $role 194 | $RetunrObjItm | add-member NoteProperty "RBAC Status" -value $RBACStatus 195 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 196 | } 197 | 198 | } 199 | 200 | } 201 | } 202 | } 203 | else 204 | { 205 | Write-Host "Please enter user or group details" 206 | } 207 | } 208 | else 209 | { 210 | Write-Host "RBACFlag is set to False.No RBAC task is performed" 211 | $RBACStatus = "RBAC Backup Flag is False.No RBAC task is performed" 212 | $RetunrObjItm = new-object PSObject 213 | $RetunrObjItm | add-member NoteProperty "RBACStatus" -value $RBACStatus 214 | } 215 | Write-Verbose "RetunrObjItm : $RetunrObjItm" 216 | Write-Output $RetunrObjItm 217 | } -------------------------------------------------------------------------------- /Scripts/Apply-RBACRoleToResources/Input-AzureVMsList.csv: -------------------------------------------------------------------------------- 1 | VM,ResourceGroup 2 | VMName1,RG-Test01 3 | VMName2,RG-Dev01 4 | -------------------------------------------------------------------------------- /Scripts/Azure Automation - ASR Recovery Plan/ASR-Get-VMSInfoFromASRContext.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [parameter(Mandatory=$true)] 3 | [Object]$RecoveryPlanContext, 4 | [parameter(Mandatory=$true)] 5 | [Boolean]$TestExecution 6 | ) 7 | 8 | Write-Verbose -Message $RecoveryPlanContext 9 | Write-Verbose "checking variable" 10 | 11 | #TESTING 12 | if($TestExecution) 13 | { 14 | Write-Verbose -Message "Using TestExecution Flag" 15 | $RecoveryPlanContextObj = $RecoveryPlanContext | ConvertFrom-Json 16 | } 17 | else 18 | { 19 | $RecoveryPlanContextObj = $RecoveryPlanContext 20 | Write-Verbose -Message "Not Using TestExecution Flag" 21 | } 22 | #TESTING 23 | 24 | 25 | #Write-Output "Using TestExecution Flag " 26 | #Change 27 | #$RecoveryPlanContextObj = $RecoveryPlanContext | ConvertFrom-Json 28 | #Write-Output "Ccheck :: $VMMapColl" 29 | 30 | Write-Verbose "getting vmmap object" 31 | $VMMapColl = $RecoveryPlanContextObj.VmMap 32 | Write-Verbose -Message $VMMapColl 33 | Write-Verbose "after getting vmmap object" 34 | 35 | $VMCollection = @() 36 | 37 | if($VMMapColl -ne $null) 38 | { 39 | Write-Verbose -Message "VMMapColl Variable is Not Null" 40 | #Write-Ouput "VMMapColl Variable is Not Null" 41 | $VMinfo = $VMMapColl | Get-Member | Where-Object MemberType -EQ NoteProperty | select -ExpandProperty Name 42 | #$vmMap = $RecoveryPlanContextObj.VmMap 43 | 44 | foreach($VMID in $VMinfo) 45 | { 46 | $VM = $VMMapColl.$VMID 47 | 48 | if( !(($VM -eq $Null) -Or ($VM.ResourceGroupName -eq $Null) -Or ($VM.RoleName -eq $Null))) 49 | { 50 | $VM | Add-Member NoteProperty RecoveryPlanName $RecoveryPlanContextObj.RecoveryPlanName 51 | $VM | Add-Member NoteProperty FailoverType $RecoveryPlanContextObj.FailoverType 52 | $VM | Add-Member NoteProperty FailoverDirection $RecoveryPlanContextObj.FailoverDirection 53 | $VM | Add-Member NoteProperty GroupId $RecoveryPlanContextObj.GroupId 54 | $VM | Add-Member NoteProperty VMId $VMID 55 | 56 | $VMCollection += $VM 57 | } 58 | } 59 | } 60 | else 61 | { 62 | Write-Verbose -Message "VMMapColl Variable is Null" 63 | } 64 | 65 | $CollectionCount = $VMCollection.Count 66 | Write-Verbose "Collection Count: $CollectionCount" 67 | 68 | #Returning Collection 69 | Write-Output $VMCollection -------------------------------------------------------------------------------- /Scripts/Azure Automation - ASR Recovery Plan/ASR-RunbookForRecoveryPlans.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [parameter(Mandatory=$true)] 3 | [Object]$RecoveryPlanContext 4 | ) 5 | 6 | $connectionName = "AzureRunAsConnection" 7 | $AutomationAccountName = "YourAutomationAccountName" 8 | $ResourceGroupName = "Resource Group Name for Automation Account" 9 | $RunbookName = "Secondary Runbook Name" 10 | $HybridWorkerGroup = "Optional" 11 | $IsSecondaryRunbookToBeRunOnHybrid = $true 12 | 13 | try 14 | { 15 | $Conn = Get-AutomationConnection -Name $connectionName 16 | 17 | # Get the connection "AzureRunAsConnection " 18 | $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName 19 | 20 | "Logging in to Azure..." 21 | Add-AzureRmAccount ` 22 | -ServicePrincipal ` 23 | -TenantId $servicePrincipalConnection.TenantId ` 24 | -ApplicationId $servicePrincipalConnection.ApplicationId ` 25 | -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 26 | 27 | Select-AzureRmSubscription -SubscriptionId $Conn.SubscriptionID -TenantId $Conn.tenantid 28 | } 29 | catch { 30 | if (!$servicePrincipalConnection) 31 | { 32 | $ErrorMessage = "Connection $connectionName not found." 33 | throw $ErrorMessage 34 | } else{ 35 | Write-Error -Message $_.Exception 36 | throw $_.Exception 37 | } 38 | } 39 | 40 | if($IsSecondaryRunbookToBeRunOnHybrid) 41 | { 42 | Start-AzureRmAutomationRunbook -AutomationAccountName $AutomationAccountName ` 43 | -ResourceGroupName $ResourceGroupName ` 44 | -Name $RunbookName ` 45 | -Parameters @{"RecoveryPlanContext"=$RecoveryPlanContext;"connectionName"=$connectionName;"AutomationAccountName"=$AutomationAccountName;"ResourceGroupName"=$ResourceGroupName;"HybridWorkerGroup"=$HybridWorkerGroup} ` 46 | -RunOn $HybridWorkerGroup 47 | } 48 | else 49 | { 50 | Start-AzureRmAutomationRunbook -AutomationAccountName $AutomationAccountName ` 51 | -ResourceGroupName $ResourceGroupName ` 52 | -Name $RunbookName ` 53 | -Parameters @{"RecoveryPlanContext"=$RecoveryPlanContext;"connectionName"=$connectionName;"AutomationAccountName"=$AutomationAccountName;"ResourceGroupName"=$ResourceGroupName;"HybridWorkerGroup"=$HybridWorkerGroup} 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /Scripts/Azure Automation - ASR Recovery Plan/RecoveryPlanContext Sample.txt: -------------------------------------------------------------------------------- 1 | { "RecoveryPlanName": "RecoveryPlan-Test", "FailoverType": "Test", "FailoverDirection": "PrimaryToSecondary", "GroupId": "Group1", "VmMap": { "aaaaaa-1111-1111-1111-aaaaaaaaaaa": { "SubscriptionId": "bbbbbbbb-2222-2222-2222-bbbbbbbbbbb", "ResourceGroupName": "rg-dr-test-asr", "CloudServiceName": null, "RoleName": "VMName-test", "RecoveryPointId": "cccccccccc-3333-3333-3333-cccccccccccc", "RecoveryPointTime": "\/Date(1550773609103)\/" } } } -------------------------------------------------------------------------------- /Scripts/Azure Automation - Check VM Availability/Check-VMAvailability.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [parameter(Mandatory=$true)] 3 | [String]$NameOfTheVM, 4 | [parameter(Mandatory=$true)] 5 | [String]$IPOfVM 6 | ) 7 | 8 | #TESTING 9 | #[String] $VMName = "cwv-webes8d-test" 10 | #[String] $VMIP = "10.21.40.206" 11 | #TESTING 12 | 13 | $HKLM = [UInt32] "0x80000002" 14 | $MachineKey = "SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" 15 | 16 | [String] $VMName = $NameOfTheVM 17 | [String] $VMIP = $IPOfVM 18 | 19 | Write-Verbose "VMName : $VMName" 20 | Write-Verbose "VMIP : $VMIP" 21 | 22 | [String] $ErrorsFound = "0" 23 | [String] $ErrorDetails = "" 24 | [Boolean] $ResultAction = $false 25 | 26 | $Cred = Get-AutomationPSCredential -Name 'AutomationCredentialName' 27 | 28 | #PING CHECK 29 | Write-Verbose "Check if VM is accessible by Ping" 30 | $PingResults = Test-Connection $VMIP -Quiet -ErrorAction SilentlyContinue -ErrorVariable PingError 31 | 32 | if($PingResults -eq $true) 33 | { 34 | #SUCCESS 35 | Write-Verbose "VM with IP $VMIP is accessible by Ping" 36 | $PingCheck = $true 37 | $PingCheckStatus = "Succeed" 38 | 39 | #PS SESSION CHECK 40 | Write-Verbose "Check if VM $VMName is accessible by PS Session" 41 | $PSession = New-PSSession -ComputerName $VMName -Credential $Cred -ErrorAction SilentlyContinue -ErrorVariable SessionError 42 | 43 | if($PSession -ne $null) 44 | { 45 | #SUCCESS 46 | Write-Verbose "VM $VMName is accessible by PS Session" 47 | $PSSessionCheck = $true 48 | $PSSessionStatus = "Succeed" 49 | 50 | Remove-PSSession -Session $PSession 51 | 52 | #Remote WMI CHECK 53 | Write-Verbose "Checking if VM with IP $VMIP is accessible by remote WMI registry" 54 | $wmi = Get-Wmiobject -list "StdRegProv" -namespace root\default -Computername $VMIP -Credential $Cred -ErrorAction SilentlyContinue -ErrorVariable ErrorWMI 55 | 56 | if($wmi -ne $null) 57 | { 58 | #SUCCESS 59 | Write-Verbose "VM with IP $VMIP is accessible by remote WMI registry" 60 | $ConnectedToWMI = $true 61 | $WMIConnectionStatus = "Succeed" 62 | Write-Verbose "Checking if VM $VMName is accessible by WinRM Connectivity" 63 | 64 | $WinRm = Test-WSMan -ComputerName $VMName -ErrorAction SilentlyContinue -ErrorVariable WinRMError 65 | 66 | if($WinRm -ne $null) 67 | { 68 | #SUCCESS 69 | $ConnectedToWinRM = $true 70 | $WinRMConnectionStatus = "Succeed" 71 | Write-Verbose "VM $VMName is accessible by WinRM Connectivity" 72 | 73 | Write-Verbose "Get FQDN from VM" 74 | $Domain = $wmi.GetStringValue($HKLM, $MachineKey, "NV Domain").sValue 75 | $FQDN = "$VMName.$Domain" 76 | Write-Verbose "FQDN from VM: $FQDN" 77 | } 78 | else 79 | { 80 | #ERROR 81 | Write-Verbose "VM $VMName is Not accessible by WinRM Connectivity" 82 | 83 | $ConnectedToWinRM = $false 84 | $WinRMConnectionStatus = "Failed" 85 | 86 | $ErrorDetails = "VM $VMName is Not accessible by WinRM Connectivity" 87 | $ErrorsFound = "1" 88 | Write-Verbose "Errors: $ErrorDetails" 89 | 90 | if($WinRMError.Count -gt 0) 91 | { 92 | $ErrorDetails = $WinRMError[0].Exception.Message 93 | Write-Verbose "Error while connecting to VM WinRM Provider Additinal Errors: $ErrorDetails" 94 | } 95 | } 96 | } 97 | else 98 | { 99 | #ERROR 100 | Write-Verbose "VM with IP $VMIP is Not accessible by remote WMI registry" 101 | 102 | $ConnectedToWMI = $false 103 | $ConnectedToWinRM = $false 104 | $WMIConnectionStatus = "Failed" 105 | $WinRMConnectionStatus = "Failed" 106 | 107 | $ErrorDetails = "VM with IP $VMIP is Not accessible by remote WMI registry" 108 | $ErrorsFound = "1" 109 | Write-Verbose "Errors: $ErrorDetails" 110 | 111 | if($ErrorWMI.Count -gt 0) 112 | { 113 | $ErrorDetails = $ErrorWMI[0].Exception.Message 114 | Write-Verbose "Error while connecting to VM WMI Provider Additinal Errors: $ErrorDetails" 115 | } 116 | } 117 | 118 | } 119 | else 120 | { 121 | #ERROR 122 | Write-Verbose "VM $VMName is Not accessible by PS Session" 123 | 124 | $PSSessionCheck = $false 125 | $ConnectedToWMI = $false 126 | $ConnectedToWinRM = $false 127 | 128 | $PSSessionStatus = "Failed" 129 | $WMIConnectionStatus = "Failed" 130 | $WinRMConnectionStatus = "Failed" 131 | 132 | $ErrorDetails = "VM $VMName is Not accessible by PS Session" 133 | $ErrorsFound = "1" 134 | Write-Verbose "Errors: $ErrorDetails" 135 | 136 | if($SessionError.Count -gt 0) 137 | { 138 | $ErrorDetails = $SessionError[0].Exception.Message 139 | Write-Verbose "Error while Check if VM $VMName is accessible by PS Session Additinal Errors: $ErrorDetails" 140 | } 141 | } 142 | } 143 | else 144 | { 145 | #ERROR 146 | Write-Verbose "VM with IP $VMIP is Not accessible by Ping" 147 | 148 | $PingCheck = $false 149 | $PSSessionCheck = $false 150 | $ConnectedToWMI = $false 151 | $ConnectedToWinRM = $false 152 | 153 | $PingCheckStatus = "Failed" 154 | $PSSessionStatus = "Failed" 155 | $WMIConnectionStatus = "Failed" 156 | $WinRMConnectionStatus = "Failed" 157 | $ErrorsFound = "1" 158 | $ErrorDetails = "VM with IP $VMIP is Not accessible by Ping" 159 | Write-Verbose "Errors: $ErrorDetails" 160 | 161 | if($PingError.Count -gt 0) 162 | { 163 | $ErrorDetails = $PingError[0].Exception.Message 164 | Write-Verbose "Error while Check if VM is accessible by Ping Additinal Errors: $ErrorDetails" 165 | } 166 | } 167 | 168 | Write-Verbose "Creating Return Object with Results" 169 | 170 | $RetunrObjItm = new-object PSObject 171 | $RetunrObjItm | add-member NoteProperty "VMName" -value $VMName 172 | $RetunrObjItm | add-member NoteProperty "VMIP" -value $VMIP 173 | $RetunrObjItm | add-member NoteProperty "VMFQDN" -value $FQDN 174 | $RetunrObjItm | add-member NoteProperty "PingCheckStatus" -value $PingCheckStatus 175 | $RetunrObjItm | add-member NoteProperty "PSSessionStatus" -value $PSSessionStatus 176 | $RetunrObjItm | add-member NoteProperty "WMIConnectionStatus" -value $WMIConnectionStatus 177 | $RetunrObjItm | add-member NoteProperty "WinRMConnectionStatus" -value $WinRMConnectionStatus 178 | $RetunrObjItm | add-member NoteProperty "ErrorsFound" -value $ErrorsFound 179 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 180 | 181 | Write-Verbose "RetunrObjItm : $RetunrObjItm" 182 | 183 | Write-Output $RetunrObjItm -------------------------------------------------------------------------------- /Scripts/Azure Automation - Get VM Information From Azure/Get-VMInfoFromAzure.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [parameter(Mandatory=$true)] 3 | [String]$NameOfVM, 4 | [parameter(Mandatory=$true)] 5 | [String]$ResourceGroupNameOfVM, 6 | [parameter(Mandatory=$true)] 7 | [String]$AzureTenantId, 8 | [parameter(Mandatory=$true)] 9 | [String] $SubscriptionID 10 | ) 11 | 12 | [String] $VMName = $NameOfVM 13 | [String] $VMResourceGroup = $ResourceGroupNameOfVM 14 | 15 | $Cred = Get-AutomationPSCredential -Name 'ServicePrincipalName' 16 | 17 | #Connect to Azure 18 | $AzureRMConn = Login-AzureRmAccount -ServicePrincipal -Credential $Cred -TenantId $AzureTenantId -ErrorAction SilentlyContinue -ErrorVariable LoginError 19 | 20 | #Check for Login Errors 21 | if($LoginError.Count -gt 0) 22 | { 23 | $ErrorDetail = $LoginError.Exception.Message; 24 | 25 | $VM | Add-Member NoteProperty Errors $ErrorDetail; 26 | } 27 | else 28 | { 29 | #Validate Connection Object Exists 30 | if($AzureRMConn -ne $null) 31 | { 32 | Write-Verbose "Setting Subscription to Id: $SubscriptionID" 33 | $ConnSubs = Select-AzureRmSubscription -SubscriptionId $SubscriptionID 34 | $VM = Get-AzureRmVM -ResourceGroupName $VMResourceGroup -Name $VMName 35 | 36 | #Change Start 37 | $nicId = $VM.NetworkProfile.NetworkInterfaces[0].Id 38 | $VMNetowrkInterface = Get-AzureRmNetworkInterface -ResourceGroupName $VMResourceGroup -Name $nicId.Split('/')[8] 39 | $VMMainIPConfig = $VMNetowrkInterface | Get-AzureRmNetworkInterfaceIpConfig 40 | 41 | $strVMMainNicName = $VMMainIPConfig.Name 42 | $strVMMainNicIPAddress = $VMMainIPConfig.PrivateIpAddress 43 | 44 | $VMName = $VM.Name 45 | 46 | $VM | Add-Member NoteProperty VMIPAddress $strVMMainNicIPAddress -force 47 | $VM | Add-Member NoteProperty VMName $VMName -force 48 | $VM | Add-Member NoteProperty VMFQDN $VMName -force 49 | $VM | Add-Member NoteProperty VMIP $strVMMainNicIPAddress -force 50 | #Change Ends 51 | 52 | } 53 | } 54 | 55 | Write-output $VM -------------------------------------------------------------------------------- /Scripts/Azure Automation - Send Email Notification/Send-EmailNotificationFromAzureAutomationRunbook.ps1: -------------------------------------------------------------------------------- 1 | Param 2 | ( 3 | [Parameter (Mandatory = $true)] 4 | [string] $SMTPServerUrl, 5 | 6 | [Parameter (Mandatory = $true)] 7 | [Int32] $SMTPServerPort, 8 | 9 | [Parameter (Mandatory = $true)] 10 | [Boolean] $UseCredentials, 11 | 12 | [Parameter (Mandatory = $false)] 13 | [string] $CredentialName, 14 | 15 | [Parameter (Mandatory = $true)] 16 | [Boolean] $EnableSsl, 17 | 18 | [Parameter (Mandatory = $true)] 19 | [string] $EmailFrom, 20 | 21 | [Parameter (Mandatory = $true)] 22 | [string] $EmailTo, 23 | 24 | [Parameter (Mandatory = $true)] 25 | [string] $EmailSubject, 26 | 27 | [Parameter (Mandatory = $true)] 28 | [string] $MessageBody 29 | 30 | ) 31 | 32 | try 33 | { 34 | if($UseCredentials -eq $true) 35 | { 36 | # RetrieveOffice 365 credential from Azure Automation Credentials 37 | $O365Credential = Get-AutomationPSCredential -Name $CredentialName 38 | } 39 | 40 | # Create new MailMessage 41 | $Message = New-Object System.Net.Mail.MailMessage 42 | 43 | # Set address-properties 44 | $Message.From = $EmailFrom 45 | $Message.replyTo = $EmailFrom 46 | $Message.To.Add($EmailTo) 47 | 48 | # Set email subject 49 | $Message.SubjectEncoding = ([System.Text.Encoding]::UTF8) 50 | $Message.Subject = $EmailSubject 51 | 52 | # Set email body 53 | $Message.Body = $MessageBody 54 | $Message.BodyEncoding = ([System.Text.Encoding]::UTF8) 55 | $Message.IsBodyHtml = $true 56 | 57 | # Create and set SMTP 58 | $SmtpClient = New-Object System.Net.Mail.SmtpClient $SMTPServerUrl, $SMTPServerPort 59 | 60 | if($UseCredentials -eq $true) 61 | { 62 | $SmtpClient.Credentials = $O365Credential 63 | } 64 | 65 | if($EnableSsl -eq $true) 66 | { 67 | $SmtpClient.EnableSsl = $true 68 | } 69 | 70 | # Send email message 71 | $SmtpClient.Send($Message) 72 | 73 | Write-Output "Email(s) Sent" 74 | } 75 | catch 76 | { 77 | $ErrorMessage = $_.Exception.Message; 78 | Write-Verbose $ErrorMessage 79 | Write-Error -Message $_.Exception 80 | } 81 | -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Apply-HubLicensing - Config.csv: -------------------------------------------------------------------------------- 1 | Computer,HUBLicensingNeeded,ResourceGroupName,OSType 2 | VMName1,Yes,Script-Dev-RG,Windows 3 | VMName2,Yes,Script-Dev-RG,Windows 4 | VMName3,no,Script-Dev-RG,Windows 5 | -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Apply-HubLicensing.ps1: -------------------------------------------------------------------------------- 1 | PARAM 2 | ( 3 | #the script input variables 4 | [Parameter(Mandatory = $True)] 5 | [Alias('Path')] 6 | [String] $ConfigFilePath = ".\Apply-HubLicensing - Config.csv", 7 | 8 | [Parameter(Mandatory = $True)] 9 | [Alias('Subscription')] 10 | [String] $SubscriptionName = "Your-Subscription-Name" 11 | ) 12 | 13 | #region Functions 14 | 15 | function Apply-HubLicensing { 16 | [CmdletBinding()] 17 | param 18 | ( 19 | [Parameter(Mandatory=$True, 20 | HelpMessage='name of the Virtual Machine')] 21 | [Alias('vm')] 22 | [string]$virtualMachineName, 23 | [Parameter(Mandatory=$True, 24 | HelpMessage='name of the Resource Group of the Virtual Machine')] 25 | [Alias('rg')] 26 | [string]$ResourceGroupName 27 | ) 28 | 29 | Write-Verbose "Applying HUB licensing on VM $virtualMachineName." 30 | $currentVm = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -ErrorAction Stop 31 | 32 | if($currentVm.storageprofile.osdisk.ostype.ToString().ToLower() -eq "windows") 33 | { 34 | Write-Host "Verified that the VM $virtualMachineName is a Windows VM." 35 | 36 | if(($currentVm.LicenseType -ne $null) -and ($currentVm.LicenseType.ToLower() -eq "windows_server")) 37 | { 38 | Write-Host "VM $virtualMachineName already has HUB license applied to it." 39 | } 40 | else 41 | { 42 | Write-Host "Verified that the VM $virtualMachineName does not have the HUB license applied to it." 43 | 44 | Write-Host "Setting the License Type for Hub Licensing" 45 | $currentVm.LicenseType = "Windows_Server" 46 | 47 | Write-Host "Updating the VM" 48 | Update-AzureRmVM -VM $currentVm -ResourceGroupName $ResourceGroupName 49 | } 50 | } 51 | else 52 | { 53 | Write-Host -ForegroundColor Red "Hub Licensing is not applicable for non-windows OS VM $virtualMachineName" 54 | } 55 | 56 | } 57 | 58 | function Test-FileExists 59 | { 60 | [CmdletBinding()] 61 | PARAM 62 | ( 63 | [Parameter(Mandatory = $true)] 64 | [ValidateNotNullOrEmpty()] 65 | [string]$SourceFile 66 | ) 67 | 68 | try 69 | { 70 | if (Test-Path $SourceFile) 71 | { 72 | Write-Debug " Located: $SourceFile. " 73 | 74 | return $true 75 | } 76 | else 77 | { 78 | Write-Debug " Could not locate: $SourceFile. " 79 | return $false 80 | } 81 | } 82 | catch [system.exception] 83 | { 84 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 85 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 86 | Write-Verbose "Error Details are: " 87 | Write-Verbose $Error[0].ToString() 88 | Stop-Transcript 89 | Exit $ERRORLEVEL 90 | } 91 | } 92 | 93 | #endregion 94 | 95 | 96 | Start-Transcript $ScriptLog 97 | Write-Verbose "======================================================================" 98 | Write-Verbose "Script Started." 99 | 100 | try 101 | { 102 | #region Login into the Azure Subscription 103 | #TODO - If you want to make script fully automated, you can change this line to use a Service Principal (i.e. An App Registration) for Loging into Azure 104 | Add-AzureRmAccount 105 | 106 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 107 | 108 | #endregion 109 | 110 | if(Test-FileExists -SourceFile $ConfigFilePath) 111 | { 112 | $configSettings = Import-Csv -Path $ConfigFilePath 113 | 114 | foreach($configSetting in $configSettings) 115 | { 116 | Apply-HubLicensing -virtualMachineName $configSetting.Computer -ResourceGroupName $configSetting.ResourceGroupName 117 | #TODO - Any Additional Code can come here 118 | } 119 | } 120 | else 121 | { 122 | Write-Host "Configuration File not found." 123 | } 124 | } 125 | catch [system.exception] 126 | { 127 | Write-Verbose "Script Error: $($_.Exception.Message) " 128 | Write-Verbose "Error Details are: " 129 | Write-Verbose $Error[0].ToString() 130 | Stop-Transcript 131 | } 132 | 133 | Write-Verbose "Script Completed. " 134 | Write-Verbose "======================================================================" 135 | Stop-Transcript 136 | #endregion -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Change-AzureVMSize - Config.csv: -------------------------------------------------------------------------------- 1 | Computer,OSType,SizeConversionNeeded,NewVMComputeSize,ResourceGroupName 2 | VM1,Windows,no,na,VM RG Name 3 | VM2,Windows,yes,Standard_DS4_v2,VM RG Name 4 | VM3,Windows,no,na,VM RG Name 5 | -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Change-AzureVMSize.ps1: -------------------------------------------------------------------------------- 1 | PARAM 2 | ( 3 | #the script input variables 4 | [Parameter(Mandatory = $True)] 5 | [Alias('Path')] 6 | [String] $ConfigFilePath = ".\Change-AzureVMSize - Config.csv", 7 | 8 | [Parameter(Mandatory = $True)] 9 | [Alias('Subscription')] 10 | [String] $SubscriptionName = "Your-Subscription-Name" 11 | ) 12 | 13 | #region Functions 14 | function Change-AzureVMSize { 15 | [CmdletBinding()] 16 | param 17 | ( 18 | [Parameter(Mandatory=$True, 19 | HelpMessage='name of the Virtual Machine')] 20 | [Alias('vm')] 21 | [string]$virtualMachineName, 22 | 23 | [Parameter(Mandatory=$True, 24 | HelpMessage='new size of the Virtual Machine')] 25 | [Alias('size')] 26 | [string]$vmSize, 27 | [Parameter(Mandatory=$True, 28 | HelpMessage='name of the Resource Group of the Virtual Machine')] 29 | [Alias('rg')] 30 | [string]$ResourceGroupName 31 | ) 32 | 33 | Write-Verbose "Fetching the VM $virtualMachineName." 34 | $currentVm = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -ErrorAction Stop 35 | 36 | if($currentVm -ne $null) 37 | { 38 | if($currentVm.HardwareProfile.VmSize -eq $vmSize ) 39 | { 40 | Write-Verbose "VM $virtualMachineName is already of size $vmSize. No further action will be take on this VM." 41 | Write-Host "VM $virtualMachineName is already of size $vmSize. No further action will be take on this VM." 42 | } 43 | else 44 | { 45 | Write-Verbose "Changing Size of the VM $virtualMachineName." 46 | $currentVm.HardwareProfile.VmSize = $vmSize 47 | 48 | Write-Verbose "Updating VM $virtualMachineName." 49 | Update-AzureRmVM -VM $currentVm -ResourceGroupName $ResourceGroupName 50 | 51 | Write-Verbose "Successfully changed size of the VM $virtualMachineName." 52 | } 53 | } 54 | else 55 | { 56 | throw "VM $virtualMachineName Not Found in resource group named $ResourceGroupName." 57 | } 58 | } 59 | 60 | function Test-FileExists 61 | { 62 | [CmdletBinding()] 63 | PARAM 64 | ( 65 | [Parameter(Mandatory = $true)] 66 | [ValidateNotNullOrEmpty()] 67 | [string]$SourceFile 68 | ) 69 | 70 | try 71 | { 72 | if (Test-Path $SourceFile) 73 | { 74 | Write-Debug " Located: $SourceFile. " 75 | 76 | return $true 77 | } 78 | else 79 | { 80 | Write-Debug " Could not locate: $SourceFile. " 81 | return $false 82 | } 83 | } 84 | catch [system.exception] 85 | { 86 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 87 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 88 | Write-Verbose "Error Details are: " 89 | Write-Verbose $Error[0].ToString() 90 | Stop-Transcript 91 | Exit $ERRORLEVEL 92 | } 93 | } 94 | 95 | #endregion 96 | 97 | 98 | Start-Transcript $ScriptLog 99 | Write-Verbose "======================================================================" 100 | Write-Verbose "Script Started." 101 | 102 | try 103 | { 104 | #region Login into the Azure Subscription 105 | #TODO - If you want to make script fully automated, you can change this line to use a Service Principal (i.e. An App Registration) for Loging into Azure 106 | Add-AzureRmAccount 107 | 108 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 109 | 110 | #endregion 111 | 112 | if(Test-FileExists -SourceFile $ConfigFilePath) 113 | { 114 | $configSettings = Import-Csv -Path $ConfigFilePath 115 | 116 | foreach($configSetting in $configSettings) 117 | { 118 | Change-AzureVMSize -virtualMachineName $configSetting.Computer -ResourceGroupName $configSetting.ResourceGroupName -vmSize $configSetting.NewVMComputeSize 119 | #TODO - Any Additional Code can come here 120 | } 121 | } 122 | else 123 | { 124 | Write-Host "Configuration File not found." 125 | } 126 | } 127 | catch [system.exception] 128 | { 129 | Write-Verbose "Script Error: $($_.Exception.Message) " 130 | Write-Verbose "Error Details are: " 131 | Write-Verbose $Error[0].ToString() 132 | Stop-Transcript 133 | } 134 | 135 | Write-Verbose "Script Completed. " 136 | Write-Verbose "======================================================================" 137 | Stop-Transcript 138 | #endregion -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Convert-VMToManagedDisk - Config.csv: -------------------------------------------------------------------------------- 1 | Computer,ManagedDiskConversion,OSType,ResourceGroupName 2 | VM1,no,Windows,Script-Dev-RG 3 | VM2,no,Windows,Script-Dev-RG 4 | VM3,yes,Windows,Script-Dev-RG 5 | -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Convert-VMToManagedDisk.ps1: -------------------------------------------------------------------------------- 1 | PARAM 2 | ( 3 | #the script input variables 4 | [Parameter(Mandatory = $True)] 5 | [Alias('Path')] 6 | [String] $ConfigFilePath = ".\Convert-VMToManagedDisk - Config.csv", 7 | 8 | [Parameter(Mandatory = $True)] 9 | [Alias('Subscription')] 10 | [String] $SubscriptionName = "Your-Subscription-Name" 11 | ) 12 | 13 | #region Functions 14 | function Convert-VMToManagedDisk { 15 | [CmdletBinding()] 16 | param 17 | ( 18 | [Parameter(Mandatory=$True, 19 | HelpMessage='name of the Virtual Machine')] 20 | [Alias('vm')] 21 | [string]$virtualMachineName, 22 | [Parameter(Mandatory=$True, 23 | HelpMessage='name of the Resource Group of the Virtual Machine')] 24 | [Alias('rg')] 25 | [string]$ResourceGroupName 26 | ) 27 | 28 | Write-Verbose "Converting the VM $virtualMachineName to Managed Disks. " 29 | 30 | $currentVm = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -ErrorAction Stop 31 | if($currentVm.StorageProfile.OsDisk.ManagedDisk -eq $null) 32 | { 33 | if($currentVm.AvailabilitySetReference -ne $null) 34 | { 35 | Write-Host "Current VM $virtualMachineName is in an Availability Set." 36 | $asIds = $currentVm.AvailabilitySetReference.Id.Split("/") 37 | $rgName = $asIds[4] 38 | $asName = $asIds[8] 39 | 40 | $avSet = Get-AzureRmAvailabilitySet -ResourceGroupName $rgName -Name $asName -ErrorAction Stop 41 | 42 | if($avSet.Managed -eq $False) 43 | { 44 | Update-AzureRmAvailabilitySet -AvailabilitySet $avSet -Managed -ErrorAction Stop 45 | } 46 | 47 | foreach($vmInfo in $avSet.VirtualMachinesReferences) 48 | { 49 | $vm = Get-AzureRmVM -ResourceGroupName $rgName | Where-Object {$_.Id -eq $vmInfo.id} 50 | 51 | if($vm.StorageProfile.OsDisk.ManagedDisk -eq $null) 52 | { 53 | Write-Host "Stopping the VM $($vm.Name)." 54 | Stop-AzureRmVM -ResourceGroupName $rgName -Name $vm.Name -Force 55 | 56 | Write-Host "Converting the VM $($vm.Name) to Managed Disks VM." 57 | ConvertTo-AzureRmVMManagedDisk -ResourceGroupName $rgName -VMName $vm.Name 58 | 59 | Start-Sleep -Seconds 600 60 | 61 | Write-Verbose "Successfully converted the VM $($vm.Name) to Managed Disks. " 62 | } 63 | else 64 | { 65 | Write-Host "VM $($vm.Name) in Availability Set $asName is already a Managed Disks VM" 66 | } 67 | 68 | } 69 | } 70 | else 71 | { 72 | Write-Host "Current VM $virtualMachineName is not in an Availability Set." 73 | 74 | Write-Host "Stopping the VM $virtualMachineName." 75 | Stop-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -Force 76 | 77 | Write-Host "Converting the VM $virtualMachineName to Managed Disks VM." 78 | ConvertTo-AzureRmVMManagedDisk -ResourceGroupName $ResourceGroupName -VMName $virtualMachineName 79 | 80 | Write-Verbose "Successfully converted the VM $virtualMachineName to Managed Disks. " 81 | } 82 | } 83 | else 84 | { 85 | Write-Host "Current VM $virtualMachineName is already Managed Disks VM." 86 | } 87 | } 88 | 89 | function Test-FileExists 90 | { 91 | [CmdletBinding()] 92 | PARAM 93 | ( 94 | [Parameter(Mandatory = $true)] 95 | [ValidateNotNullOrEmpty()] 96 | [string]$SourceFile 97 | ) 98 | 99 | try 100 | { 101 | if (Test-Path $SourceFile) 102 | { 103 | Write-Debug " Located: $SourceFile. " 104 | 105 | return $true 106 | } 107 | else 108 | { 109 | Write-Debug " Could not locate: $SourceFile. " 110 | return $false 111 | } 112 | } 113 | catch [system.exception] 114 | { 115 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 116 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 117 | Write-Verbose "Error Details are: " 118 | Write-Verbose $Error[0].ToString() 119 | Stop-Transcript 120 | Exit $ERRORLEVEL 121 | } 122 | } 123 | 124 | #endregion 125 | 126 | 127 | Start-Transcript $ScriptLog 128 | Write-Verbose "======================================================================" 129 | Write-Verbose "Script Started." 130 | 131 | try 132 | { 133 | #region Login into the Azure Subscription 134 | #TODO - If you want to make script fully automated, you can change this line to use a Service Principal (i.e. An App Registration) for Loging into Azure 135 | Add-AzureRmAccount 136 | 137 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 138 | 139 | #endregion 140 | 141 | if(Test-FileExists -SourceFile $ConfigFilePath) 142 | { 143 | $configSettings = Import-Csv -Path $ConfigFilePath 144 | 145 | foreach($configSetting in $configSettings) 146 | { 147 | Convert-VMToManagedDisk -virtualMachineName $configSetting.Computer -ResourceGroupName $configSetting.ResourceGroupName 148 | #TODO - Any Additional Code can come here 149 | } 150 | } 151 | else 152 | { 153 | Write-Host "Configuration File not found." 154 | } 155 | } 156 | catch [system.exception] 157 | { 158 | Write-Verbose "Script Error: $($_.Exception.Message) " 159 | Write-Verbose "Error Details are: " 160 | Write-Verbose $Error[0].ToString() 161 | Stop-Transcript 162 | } 163 | 164 | Write-Verbose "Script Completed. " 165 | Write-Verbose "======================================================================" 166 | Stop-Transcript 167 | #endregion -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Enable-VMBackup - Config.csv: -------------------------------------------------------------------------------- 1 | Computer,OSType,ResourceGroupName,EnableBackup,RecoveryServicesVaultName,BackupProtectionPolicy 2 | VMName1,Windows,Script-Dev-RG,no,na,na 3 | VMName2,Windows,Script-Dev-RG,yes,ARMBackup-CentralUS,Daily-30--Weekly-8--Monthly-6 4 | VMName3,Windows,Script-Dev-RG,yes,ARMBackup-CentralUS,Daily-30--Weekly-8--Monthly-6 5 | -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Enable-VMBackup.ps1: -------------------------------------------------------------------------------- 1 | PARAM 2 | ( 3 | #the script input variables 4 | [Parameter(Mandatory = $True)] 5 | [Alias('Path')] 6 | [String] $ConfigFilePath = ".\Enable-VMBackup - Config.csv", 7 | 8 | [Parameter(Mandatory = $True)] 9 | [Alias('Subscription')] 10 | [String] $SubscriptionName = "Your-Subscription-Name" 11 | ) 12 | 13 | #region Functions 14 | function Enable-VMBackup { 15 | [CmdletBinding()] 16 | param 17 | ( 18 | [Parameter(Mandatory=$True, 19 | HelpMessage='name of the Virtual Machine')] 20 | [Alias('vm')] 21 | [string]$virtualMachineName, 22 | 23 | [Parameter(Mandatory=$True, 24 | HelpMessage='name of the Recovery Services Vault ')] 25 | [Alias('vault')] 26 | [string]$RecoveryServicesVaultName, 27 | 28 | [Parameter(Mandatory=$True, 29 | HelpMessage='name of the Backup Protection Policy ')] 30 | [Alias('policy')] 31 | [string]$BackupProtectionPolicy, 32 | 33 | [Parameter(Mandatory=$True, 34 | HelpMessage='name of the Resource Group of the Virtual Machine')] 35 | [Alias('rg')] 36 | [string]$ResourceGroupName 37 | ) 38 | 39 | Write-Verbose "Enabling Backup on the VM $virtualMachineName." 40 | 41 | Write-Host "Fetching the Recovery Services Vault" 42 | $recoveryServicesVault = Get-AzureRmRecoveryServicesVault -Name $RecoveryServicesVaultName 43 | 44 | if($recoveryServicesVault -eq $null) 45 | { 46 | throw "Recovery Services Vault $RecoveryServicesVaultName not found in the current subscription." 47 | } 48 | 49 | Write-Host "Setting up the Recovery Services Vault Context" 50 | $recoveryServicesVault | Set-AzureRmRecoveryServicesVaultContext -ErrorAction Stop 51 | 52 | 53 | #Check if backup is already configured 54 | $namedContainerCheck = Get-AzureRmRecoveryServicesBackupContainer -ContainerType "AzureVM" -Status "Registered" -FriendlyName $virtualMachineName 55 | 56 | if($namedContainerCheck -ne $null) 57 | { 58 | Write-Host "Backup is already configured on the VM $virtualMachineName" 59 | } 60 | else 61 | { 62 | #Enabling Backup 63 | Write-Host "Fetching the Backup Policy" 64 | $policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -WorkloadType "AzureVM" | where {$_.Name -eq $BackupProtectionPolicy} 65 | 66 | if($policy -eq $null) 67 | { 68 | throw "Recovery Policy $BackupProtectionPolicy is not found in the Vault $RecoveryServicesVaultName" 69 | } 70 | 71 | Write-Host "Enabling Backup on the VM" 72 | Enable-AzureRmRecoveryServicesBackupProtection -Policy $policy -Name $virtualMachineName -ResourceGroupName $ResourceGroupName -ErrorAction Stop 73 | 74 | #Triggering a Backup 75 | Write-Host "Fetching the Recovery Services Backup Container" 76 | $namedContainer = Get-AzureRmRecoveryServicesBackupContainer -ContainerType "AzureVM" -Status "Registered" -FriendlyName $virtualMachineName 77 | Write-Host "Fetching the Recovery Services Backup Item" 78 | $item = Get-AzureRmRecoveryServicesBackupItem -Container $namedContainer -WorkloadType "AzureVM" 79 | Write-Host "Triggering a Backup on the VM" 80 | $job = Backup-AzureRmRecoveryServicesBackupItem -Item $item 81 | 82 | Write-Host "Successfully Enabled the Backup on the VM $virtualMachineName" 83 | } 84 | } 85 | 86 | function Test-FileExists 87 | { 88 | [CmdletBinding()] 89 | PARAM 90 | ( 91 | [Parameter(Mandatory = $true)] 92 | [ValidateNotNullOrEmpty()] 93 | [string]$SourceFile 94 | ) 95 | 96 | try 97 | { 98 | if (Test-Path $SourceFile) 99 | { 100 | Write-Debug " Located: $SourceFile. " 101 | 102 | return $true 103 | } 104 | else 105 | { 106 | Write-Debug " Could not locate: $SourceFile. " 107 | return $false 108 | } 109 | } 110 | catch [system.exception] 111 | { 112 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 113 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 114 | Write-Verbose "Error Details are: " 115 | Write-Verbose $Error[0].ToString() 116 | Stop-Transcript 117 | Exit $ERRORLEVEL 118 | } 119 | } 120 | 121 | #endregion 122 | 123 | 124 | Start-Transcript $ScriptLog 125 | Write-Verbose "======================================================================" 126 | Write-Verbose "Script Started." 127 | 128 | try 129 | { 130 | #region Login into the Azure Subscription 131 | #TODO - If you want to make script fully automated, you can change this line to use a Service Principal (i.e. An App Registration) for Loging into Azure 132 | Add-AzureRmAccount 133 | 134 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 135 | 136 | #endregion 137 | 138 | if(Test-FileExists -SourceFile $ConfigFilePath) 139 | { 140 | $configSettings = Import-Csv -Path $ConfigFilePath 141 | 142 | foreach($configSetting in $configSettings) 143 | { 144 | Enable-VMBackup -virtualMachineName $configSetting.Computer -ResourceGroupName $configSetting.ResourceGroupName -RecoveryServicesVaultName $configSetting.RecoveryServicesVaultName -BackupProtectionPolicy $configSetting.BackupProtectionPolicy 145 | #TODO - Any Additional Code can come here 146 | } 147 | } 148 | else 149 | { 150 | Write-Host "Configuration File not found." 151 | } 152 | } 153 | catch [system.exception] 154 | { 155 | Write-Verbose "Script Error: $($_.Exception.Message) " 156 | Write-Verbose "Error Details are: " 157 | Write-Verbose $Error[0].ToString() 158 | Stop-Transcript 159 | } 160 | 161 | Write-Verbose "Script Completed. " 162 | Write-Verbose "======================================================================" 163 | Stop-Transcript 164 | #endregion -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Export-VMConfig - Config.csv: -------------------------------------------------------------------------------- 1 | Computer,OSType,ResourceGroupName 2 | VMName1,Windows,Script-Dev-RG 3 | VMName2,Windows,Script-Dev-RG 4 | VMName3,Windows,Script-Dev-RG 5 | -------------------------------------------------------------------------------- /Scripts/Azure VM Operations/Export-VMConfig.ps1: -------------------------------------------------------------------------------- 1 | PARAM 2 | ( 3 | #the script input variables 4 | [Parameter(Mandatory = $True)] 5 | [Alias('Path')] 6 | [String] $ConfigFilePath = ".\Export-VMConfig - Config.csv", 7 | 8 | [Parameter(Mandatory = $True)] 9 | [Alias('Subscription')] 10 | [String] $SubscriptionName = "Your-Subscription-Name" 11 | ) 12 | 13 | #region Functions 14 | function Export-VMConfig { 15 | [CmdletBinding()] 16 | param 17 | ( 18 | [Parameter(Mandatory=$True, 19 | HelpMessage='name of the Virtual Machine')] 20 | [Alias('vm')] 21 | [string]$virtualMachineName, 22 | 23 | [Parameter(Mandatory=$True, 24 | HelpMessage='name of the Resource Group of the Virtual Machine')] 25 | [Alias('rg')] 26 | [string]$ResourceGroupName, 27 | 28 | [Parameter(Mandatory=$True, 29 | HelpMessage='name of the Stage of Operation')] 30 | [Alias('stage')] 31 | [string]$OperationStage 32 | ) 33 | try 34 | { 35 | Write-Verbose "Exporting Information for VM $virtualMachineName." 36 | $currentVm = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -ErrorAction Stop 37 | 38 | $timeStamp = (Get-Date).ToString("MM-dd-yyyy-HH-mm-ss") 39 | $fileName = $virtualMachineName + "-" + $OperationStage + "-" + $timeStamp + '.json' 40 | 41 | Write-Host "Outputing VM configurations for VM $virtualMachineName at stage $OperationStage at time $timeStamp ." 42 | $currentVm | ConvertTo-Json -Depth 100 | Out-File -FilePath $fileName 43 | 44 | Write-Verbose "Successfully information for the VM $virtualMachineName." 45 | } 46 | catch [system.exception] 47 | { 48 | Write-Verbose "Failed to export the information for VM $virtualMachineName. " 49 | Write-Verbose "Error in Change-AzureVMSize(): $($_.Exception.Message) " 50 | Write-Host "Error in Change-AzureVMSize() for $virtualMachineName : $($_.Exception.Message) " 51 | Write-Verbose "Error Details are: " 52 | Write-Verbose $Error[0].ToString() 53 | Stop-Transcript 54 | 55 | Export-VMOperation 56 | Exit $ERRORLEVEL 57 | } 58 | } 59 | 60 | function Test-FileExists 61 | { 62 | [CmdletBinding()] 63 | PARAM 64 | ( 65 | [Parameter(Mandatory = $true)] 66 | [ValidateNotNullOrEmpty()] 67 | [string]$SourceFile 68 | ) 69 | 70 | try 71 | { 72 | if (Test-Path $SourceFile) 73 | { 74 | Write-Debug " Located: $SourceFile. " 75 | 76 | return $true 77 | } 78 | else 79 | { 80 | Write-Debug " Could not locate: $SourceFile. " 81 | return $false 82 | } 83 | } 84 | catch [system.exception] 85 | { 86 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 87 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 88 | Write-Verbose "Error Details are: " 89 | Write-Verbose $Error[0].ToString() 90 | Stop-Transcript 91 | Exit $ERRORLEVEL 92 | } 93 | } 94 | 95 | #endregion 96 | 97 | 98 | Start-Transcript $ScriptLog 99 | Write-Verbose "======================================================================" 100 | Write-Verbose "Script Started." 101 | 102 | try 103 | { 104 | #region Login into the Azure Subscription 105 | #TODO - If you want to make script fully automated, you can change this line to use a Service Principal (i.e. An App Registration) for Loging into Azure 106 | Add-AzureRmAccount 107 | 108 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 109 | 110 | #endregion 111 | 112 | if(Test-FileExists -SourceFile $ConfigFilePath) 113 | { 114 | $configSettings = Import-Csv -Path $ConfigFilePath 115 | 116 | foreach($configSetting in $configSettings) 117 | { 118 | Export-VMConfig -virtualMachineName $configSetting.Computer -OperationStage "Processing" -ResourceGroupName $configSetting.ResourceGroupName 119 | #TODO - Any Additional Code can come here 120 | } 121 | } 122 | else 123 | { 124 | Write-Host "Configuration File not found." 125 | } 126 | } 127 | catch [system.exception] 128 | { 129 | Write-Verbose "Script Error: $($_.Exception.Message) " 130 | Write-Verbose "Error Details are: " 131 | Write-Verbose $Error[0].ToString() 132 | Stop-Transcript 133 | } 134 | 135 | Write-Verbose "Script Completed. " 136 | Write-Verbose "======================================================================" 137 | Stop-Transcript 138 | #endregion -------------------------------------------------------------------------------- /Scripts/Create-ResourceGroupsWithRBACAssignments/Create-ResourceGroupsWithRBACAssignments.ps1: -------------------------------------------------------------------------------- 1 | $RGNamesUSE = "RG-01-Test-USE", "RG-02-Test-USE", "RG-03-Test-USE", "RG-03-Test-USE","RG-04-Test-USE" 2 | $RGNamesUSNC = "RG-01-Test-USNC", "RG-02-Test-USNC", "RG-03-Test-USNC", "RG-04-Test-USNC" 3 | 4 | 5 | Add-AzureRmAccount 6 | Select-AzureRmSubscription -SubscriptionName "SubscriptionName" 7 | 8 | $ADGroup01 = Get-AzureRmADGroup -SearchString "ADGroup-01-Test-Contributors" 9 | $App01 = Get-AzureRmADServicePrincipal -SearchString "AD-AppRegistration01-Test" 10 | $ADGroup02 = Get-AzureRmADGroup -SearchString "ADGroup-02-Test-Readers" 11 | 12 | foreach($rg in $RGNamesUSE) 13 | { 14 | New-AzureRmResourceGroup -Name $rg -Location eastus 15 | 16 | New-AzureRmRoleAssignment -ObjectId $ADGroup01.Id -RoleDefinitionName "Contributor" -ResourceGroupName $rg 17 | 18 | New-AzureRmRoleAssignment -ObjectId $App01.Id -RoleDefinitionName "Contributor" -ResourceGroupName $rg 19 | 20 | #Remove-AzureRmRoleAssignment -ObjectId $ADGroup02.Id -RoleDefinitionName "Contributor" -ResourceGroupName $rg 21 | New-AzureRmRoleAssignment -ObjectId $ADGroup02.Id -RoleDefinitionName "Reader" -ResourceGroupName $rg 22 | 23 | } 24 | foreach($rg in $RGNamesUSNC) 25 | { 26 | New-AzureRmResourceGroup -Name $rg -Location northcentralus 27 | 28 | New-AzureRmRoleAssignment -ObjectId $ADGroup01.Id -RoleDefinitionName "Contributor" -ResourceGroupName $rg 29 | 30 | New-AzureRmRoleAssignment -ObjectId $App01.Id -RoleDefinitionName "Contributor" -ResourceGroupName $rg 31 | 32 | #Remove-AzureRmRoleAssignment -ObjectId $ADGroup02.Id -RoleDefinitionName "Contributor" -ResourceGroupName $rg 33 | New-AzureRmRoleAssignment -ObjectId $ADGroup02.Id -RoleDefinitionName "Reader" -ResourceGroupName $rg 34 | } -------------------------------------------------------------------------------- /Scripts/Enable-RHELBYOSLicense/Enable-RHELBYOSLicense.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | File: Enable-RHELBYOLLicense.ps1 5 | 6 | Purpose: To enable RHEL BYOL on Azure VMs 7 | 8 | Version: 1.0.0.0 9 | 10 | Author: Aman Sharma 11 | ============================================================================================== 12 | .SYNOPSIS 13 | To enable RHEL BYOL on Azure VMs 14 | 15 | .DESCRIPTION 16 | This script is used to enable RHEL BYOL on Azure VMs 17 | 18 | .EXAMPLE 19 | C:\PS> .\Enable-RHELBYOLLicense.ps1 20 | 21 | Description 22 | ----------- 23 | This command executes the script with default parameters. 24 | 25 | .INPUTS 26 | None. 27 | 28 | .OUTPUTS 29 | None. 30 | 31 | .LINK 32 | None. 33 | #> 34 | 35 | #Inputs 36 | $subscriptionName = "Your-Subscription-Name-Here" 37 | 38 | #Adding Azure Account and Subscription 39 | $env = Get-AzEnvironment -Name "AzureCloud" 40 | Connect-AzAccount -Environment $env 41 | Set-AzContext -SubscriptionName $subscriptionName 42 | 43 | #Selecting all RGs that begins with the text. Notice the wildcard in the name 44 | $allRHELRGs = Get-AzResourceGroup -Name "RG-IT-*" 45 | 46 | foreach($currentRG in $allRHELRGs) 47 | { 48 | #Fetch all VMs in the RG 49 | $currentRGName = $currentRG.ResourceGroupName 50 | $VMs = Get-AzVM -ResourceGroupName $currentRGName 51 | 52 | #Iterating through all VMs in the RG 53 | foreach ($vm in $VMs) 54 | { 55 | $VMName = $vm.name 56 | $osType = $vm.StorageProfile.OsDisk.OsType 57 | Write-Host "Working on VM: $VMName" 58 | 59 | #Checking if the OS type is Linux or not for the VM 60 | if ($osType -eq "Linux") { 61 | Write-Host "VM $VMName is a Linux VM" 62 | try { 63 | #Setting the License Type 64 | $vm.LicenseType = "RHEL_BYOS" 65 | #Updating the VM with the License type 66 | Update-AzVM -VM $vm -ResourceGroupName $currentRGName 67 | Write-Host -ForegroundColor Green "Set the License type to RHEL_BYOS on $VMName" 68 | } 69 | catch { 70 | # Printing Error details 71 | Write-Host -ForegroundColor Red "Error while setting License type." 72 | $Error[0] 73 | Write-Host -ForegroundColor Red "Error occured at:" 74 | $Error[0].InvocationInfo.PositionMessage 75 | } 76 | } 77 | else { 78 | #The VM is not a Linux VM 79 | Write-Host "VM $VMName is not a Linux VM" 80 | } 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Scripts/Enable-SUSEBYOSLicense/Enable-SUSEBYOSLicense.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | File: Enable-SUSEBYOLLicense.ps1 5 | 6 | Purpose: To enable SUSE BYOL on Azure VMs 7 | 8 | Version: 1.0.0.0 9 | 10 | Author: Aman Sharma 11 | ============================================================================================== 12 | .SYNOPSIS 13 | To enable SUSE BYOL on Azure VMs 14 | 15 | .DESCRIPTION 16 | This script is used to enable SUSE BYOL on Azure VMs 17 | 18 | .EXAMPLE 19 | C:\PS> .\Enable-SUSEBYOLLicense.ps1 20 | 21 | Description 22 | ----------- 23 | This command executes the script with default parameters. 24 | 25 | .INPUTS 26 | None. 27 | 28 | .OUTPUTS 29 | None. 30 | 31 | .LINK 32 | None. 33 | #> 34 | 35 | #Inputs 36 | $subscriptionName = "Your-Subscription-Name-Here" 37 | 38 | #Adding Azure Account and Subscription 39 | $env = Get-AzEnvironment -Name "AzureCloud" 40 | Connect-AzAccount -Environment $env 41 | Set-AzContext -SubscriptionName $subscriptionName 42 | 43 | #Selecting all RGs that begins with the text. Notice the wildcard in the name 44 | $allSUSERGs = Get-AzResourceGroup -Name "RG-IT-*" 45 | 46 | foreach($currentRG in $allSUSERGs) 47 | { 48 | #Fetch all VMs in the RG 49 | $currentRGName = $currentRG.ResourceGroupName 50 | $VMs = Get-AzVM -ResourceGroupName $currentRGName 51 | 52 | #Iterating through all VMs in the RG 53 | foreach ($vm in $VMs) 54 | { 55 | $VMName = $vm.name 56 | $osType = $vm.StorageProfile.OsDisk.OsType 57 | Write-Host "Working on VM: $VMName" 58 | 59 | #Checking if the OS type is Linux or not for the VM 60 | if ($osType -eq "Linux") { 61 | Write-Host "VM $VMName is a Linux VM" 62 | try { 63 | #Setting the License Type 64 | $vm.LicenseType = "SLES_BYOS" 65 | #Updating the VM with the License type 66 | Update-AzVM -VM $vm -ResourceGroupName $currentRGName 67 | Write-Host -ForegroundColor Green "Set the License type to SLES_BYOS on $VMName" 68 | } 69 | catch { 70 | # Printing Error details 71 | Write-Host -ForegroundColor Red "Error while setting License type." 72 | $Error[0] 73 | Write-Host -ForegroundColor Red "Error occured at:" 74 | $Error[0].InvocationInfo.PositionMessage 75 | } 76 | } 77 | else { 78 | #The VM is not a Linux VM 79 | Write-Host "VM $VMName is not a Linux VM" 80 | } 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Scripts/Enable-WindowsAdminCenter/Enable-WindowsAdminCenter.ps1: -------------------------------------------------------------------------------- 1 | #Author: Aman Sharma @ http://HarvestingClouds.com 2 | 3 | #Variables 4 | $subscriptionName = "Your Subscription Name" 5 | $salt = "" 6 | $wacPort = "6516" 7 | $Settings = @{"port" = $wacPort; "salt" = $salt} 8 | 9 | try 10 | { 11 | #Setting the Azure context 12 | $env = Get-AzEnvironment -Name "AzureCloud" 13 | Connect-AzAccount -Environment $env 14 | Set-AzContext -SubscriptionName $subscriptionName 15 | 16 | #Selecting all RGs that begins with the text. Notice the wildcard in the name 17 | #Update this as per your requirements 18 | $allRequiredRGs = Get-AzResourceGroup -Name "RG-*" 19 | 20 | #Iterating on the Resource Groups 21 | foreach($currentRG in $allRequiredRGs) 22 | { 23 | #Fetch all VMs in the current Resource Group 24 | $currentRGName = $currentRG.ResourceGroupName 25 | $VMs = Get-AzVM -ResourceGroupName $currentRGName 26 | 27 | #Iterating on all the VMs 28 | foreach ($vm in $VMs) 29 | { 30 | $vmLocation = $vm.Location 31 | $vmName = $vm.Name 32 | 33 | #Finding VM's NSG dynamically 34 | $vmNsgId = (Get-AzNetworkInterface -ResourceId $vm.NetworkProfile.NetworkInterfaces.Id).NetworkSecurityGroup.Id 35 | $vmNsg = Get-AzResource -ResourceId $vmNsgId 36 | $vmNsgName = $vmNsg.Name 37 | 38 | # Open outbound port rule for WAC service 39 | $vmNsg | Add-AzNetworkSecurityRuleConfig -Name "PortForWACService" -Access "Allow" -Direction "Outbound" -SourceAddressPrefix "VirtualNetwork" -SourcePortRange "*" -DestinationAddressPrefix "WindowsAdminCenter" -DestinationPortRange "443" -Priority 100 -Protocol Tcp | Set-AzNetworkSecurityGroup 40 | 41 | # Install VM extension 42 | Set-AzVMExtension -ResourceGroupName $currentRGName -Location $vmLocation -VMName $vmName -Name "AdminCenter" -Publisher "Microsoft.AdminCenter" -Type "AdminCenter" -TypeHandlerVersion "0.0" -settings $Settings 43 | 44 | # Open inbound port rule on VM to be able to connect to WAC 45 | $vmNsg | Add-AzNetworkSecurityRuleConfig -Name "PortForWAC" -Access "Allow" -Direction "Inbound" -SourceAddressPrefix "*" -SourcePortRange "*" -DestinationAddressPrefix "*" -DestinationPortRange $wacPort -Priority 100 -Protocol Tcp | Set-AzNetworkSecurityGroup 46 | 47 | } 48 | 49 | } 50 | } 51 | catch 52 | { 53 | Write-Host -ForegroundColor Red "Error while installing extension." 54 | $Error[0] 55 | Write-Host -ForegroundColor Red "Error occured at:" 56 | $Error[0].InvocationInfo.PositionMessage 57 | } 58 | -------------------------------------------------------------------------------- /Scripts/Export-AllAutomationRunbooksAndVariables/Export-AllAutomationRunbooksAndVariables.ps1: -------------------------------------------------------------------------------- 1 | $SubscriptionName = "SubscriptionName" 2 | $AutomationAccountName = "Automation Account Name" 3 | $ResourceGroupName = "Resource Group of Automation Account" 4 | $OutputFolder = "Output Folder Full Path without trailing slash sign" 5 | 6 | #region Loggin in and selecting Subscription 7 | Add-AzureRmAccount 8 | 9 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 10 | 11 | #endregion 12 | 13 | #region 1. Exporting Runbooks 14 | 15 | $AllRunbooks = Get-AzureRmAutomationRunbook -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName 16 | $AllRunbooks | Export-AzureRmAutomationRunbook -OutputFolder $OutputFolder 17 | 18 | #endregion 19 | 20 | 21 | #region 2. Exporting Variables 22 | 23 | $variables = Get-AzureRmAutomationVariable -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName 24 | 25 | $variablesFilePath = $OutputFolder + "\variables.csv" 26 | 27 | $variables | Export-Csv -Path $variablesFilePath -NoTypeInformation 28 | 29 | #endregion -------------------------------------------------------------------------------- /Scripts/Export-AllAzureCustomPolicies/Export-AllAzureCustomPolicies.ps1: -------------------------------------------------------------------------------- 1 | #Reference: https://docs.microsoft.com/en-us/azure/governance/policy/how-to/export-resources#export-with-azure-powershell 2 | #Logging into Azure 3 | $env = Get-AzEnvironment -Name "AzureCloud" 4 | Connect-AzAccount -Environment $env 5 | 6 | #Getting all Subscriptions in your environment 7 | $allSubscriptions = Get-AzSubscription 8 | 9 | #Iterating through subscriptions 10 | foreach($currentSubscription in $allSubscriptions) 11 | { 12 | #setting the context to the current subscription 13 | Set-AzContext -SubscriptionName $currentSubscription.Name 14 | 15 | #Getting all the custom policies 16 | $policies = Get-AzPolicyDefinition | where {$_.PolicyType -eq 'Custom'} 17 | 18 | #Iterating through the policies 19 | foreach ($policy in $policies) { 20 | 21 | #Getting the policy details 22 | $policyName = $policy.Name 23 | $fileName = $currentSubscription.Name + "_" + $policyName + ".json" 24 | 25 | #Exporting the current custom policy 26 | $policy | ConvertTo-Json -Depth 10 | Out-File ".\Export-AzurePolicies\Output\$fileName" 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Scripts/Export-OMSLogAnalyticsSavedSearches/Export-OMSLogAnalyticsSavedSearches.ps1: -------------------------------------------------------------------------------- 1 | $ResourceGroupName = "Resource Group of Workspace" 2 | $WorkspaceName = "Your Workspace Name" 3 | $SubscriptionName = "YourSubscriptionName" 4 | 5 | Add-AzureRmAccount 6 | 7 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 8 | 9 | # Export Saved Searches 10 | (Get-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName).Value.Properties | ConvertTo-Json -------------------------------------------------------------------------------- /Scripts/Format-EABillingUsageCsvForTags/Format-EABillingUsageCsvForTags.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Microsoft Corporation. All rights reserved. 5 | 6 | File: Format-EABillingUsageCsvForTags.ps1 7 | 8 | Purpose: To parse and format the Billing Usage CSV and split the Tags as per the standards 9 | 10 | Version: 1.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Azure Resources Billing Usage Report Formatting Script as per Tags 16 | 17 | .DESCRIPTION 18 | This script is used to parse and format the Billing Usage CSV and split the Tags as per the standards. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Format-EABillingUsageCsvForTags.ps1 -PathOfInputBillingUsageCsv "Your-Usage-File-Path-Here" 22 | 23 | Description 24 | ----------- 25 | This script is used to parse and format the Billing Usage CSV and split the Tags as per the standards. 26 | 27 | .PARAMETER PathOfInputBillingUsageCsv 28 | This is the path to the Billing Usage Csv that we want to format as per Tags. 29 | 30 | .INPUTS 31 | None. 32 | 33 | .OUTPUTS 34 | None. 35 | 36 | .LINK 37 | None. 38 | #> 39 | 40 | #Path variable to the CSV file 41 | $PathOfInputBillingUsageCsv = "C:\FullPath\Sample Input - EA Azure Billing CSV.csv" 42 | 43 | $dateTime = Get-Date -Format "yyyy-MM-dd-hh-mm" 44 | $PathToOutputCSVReport = "C:\FullPath\UsageWithTags-"+ $dateTime +".csv" 45 | 46 | if(Test-Path $PathOfInputBillingUsageCsv) 47 | { 48 | #Iterating the CSV file 49 | Import-CSV -Path $PathOfInputBillingUsageCsv | 50 | ForEach-Object { 51 | #Parsing values from the CSV file 52 | $tags = $null 53 | $tags = $_.Tags 54 | 55 | 56 | #Declaring variables for Tags 57 | #TODO 1 - Change these to the actual tags in your environment 58 | $ApplicationOwner = "" 59 | $ApplicationType = "" 60 | $BusinessUnit = "" 61 | $Department = "" 62 | 63 | #region Parsing Tags 64 | 65 | if(($tags -ne $null) -and ($tags -ne "")) 66 | { 67 | #Converting tags to PowerShell variable 68 | $psTags = $null 69 | #TODO 2 - Change these to the actual tags in your environment 70 | $tags1 = $tags.Replace("ApplicationOwner","ApplicationOwner1").Replace("ApplicationType","ApplicationType1").Replace("Department","Department1").Replace("BusinessUnit","BusinessUnit1") 71 | 72 | $psTags = ConvertFrom-Json $tags1 73 | 74 | #TODO 3 - Change these to the actual tags in your environment 75 | if($tags1.Contains("ApplicationOwner1")) 76 | { 77 | $ApplicationOwner = $psTags.ApplicationOwner1 78 | } 79 | if($tags1.Contains("Application Owner")) 80 | { 81 | $ApplicationOwner = $psTags."Application Owner" 82 | } 83 | if($tags1.Contains("ApplicationType1")) 84 | { 85 | $ApplicationType = $psTags.ApplicationType1 86 | } 87 | if($tags1.Contains("Application Type")) 88 | { 89 | $ApplicationType = $psTags."Application Type" 90 | } 91 | if($tags1.Contains("BusinessUnit1")) 92 | { 93 | $BusinessUnit = $psTags.BusinessUnit1 94 | } 95 | if($tags1.Contains("Business Unit")) 96 | { 97 | $BusinessUnit = $psTags."Business Unit" 98 | } 99 | if($tags1.Contains("Department1")) 100 | { 101 | $Department = $psTags.Department1 102 | } 103 | } 104 | #endregion 105 | 106 | #TODO 4 - Change these to the actual tags in your environment 107 | $_ | 108 | Add-Member -MemberType NoteProperty -Name ApplicationOwner -Value $ApplicationOwner -PassThru | 109 | Add-Member -MemberType NoteProperty -Name ApplicationType -Value $ApplicationType -PassThru | 110 | Add-Member -MemberType NoteProperty -Name BusinessUnit -Value $BusinessUnit -PassThru | 111 | Add-Member -MemberType NoteProperty -Name Department -Value $Department -PassThru 112 | 113 | } | 114 | Export-CSV $PathToOutputCSVReport -NoTypeInformation -ErrorAction Stop 115 | 116 | Write-Host "Generated the new CSV file. The file with complete path is: $PathToOutputCSVReport" -ForegroundColor Green 117 | } 118 | else 119 | { 120 | Write-Host "Error - File not found at the path:" -ForegroundColor Red 121 | Write-Host $PathOfInputBillingUsageCsv 122 | } -------------------------------------------------------------------------------- /Scripts/Format-EABillingUsageCsvForTags/Input Sample - EA Azure Billing CSV.csv: -------------------------------------------------------------------------------- 1 | AccountOwnerId,Account Name,ServiceAdministratorId,SubscriptionId,SubscriptionGuid,Subscription Name,Date,Month,Day,Year,Product,Meter ID,Meter Category,Meter Sub-Category,Meter Region,Meter Name,Consumed Quantity,ResourceRate,ExtendedCost,Resource Location,Consumed Service,Instance ID,ServiceInfo1,ServiceInfo2,AdditionalInfo,Tags,Store Service Identifier,Department Name,Cost Center,Unit Of Measure,Resource Group 2 | aman.sharma@harvestingclouds.com,Aman Sharma,,0,aaaaaaaa-1111-1111-1111-aaaaaaaaaaa,Your-Subscription-Name,1/1/2018,1,1,2018,Data Transfer Out - Zone 1,9995d93a-7d35-4d3f-9c69-7a7fea447ef4,Networking,Networking,Zone 1,Data Transfer Out (GB),0.004505,0.049998245,0.000225242,EastUS2,Microsoft.Compute,/subscriptions/aaaaaaaa-1111-1111-1111-aaaaaaaaaaa/resourceGroups/RG-TEST-USE2/providers/Microsoft.Compute/virtualMachines/VMName01,,,"{ ""ImageType"": """", ""ServiceType"": """", ""VMName"": """", ""VMProperties"": """", ""UsageType"": ""DataTrOut""}","{ ""ApplicationOwner"": ""aman@domain.com"", ""BusinessUnit"": ""Infrastructure"", ""ApplicationType"": ""Test"", ""Department"": ""Operations""}",,Unassigned,,GB,RG-TEST-USE2 3 | aman.sharma@harvestingclouds.com,Aman Sharma,,0,aaaaaaaa-1111-1111-1111-aaaaaaaaaaa,Your-Subscription-Name,5/9/2018,1,1,2018,BASIC.A2 VM (Windows) - US East 2,f1cba056-ef57-4ce1-831b-b67168724adb,Virtual Machines,BASIC.A2 VM (Windows),US East 2,Compute Hours,1,0.09,0.09,EastUS2,Microsoft.Compute,/subscriptions/aaaaaaaa-1111-1111-1111-aaaaaaaaaaa/resourceGroups/RG-TEST-USE2/providers/Microsoft.Compute/virtualMachines/VMName01,,,"{ ""ImageType"": """", ""ServiceType"": ""Basic_A2"", ""VMName"": """", ""VMProperties"": """", ""UsageType"": ""ComputeHR""}","{ ""ApplicationOwner"": ""aman@domain.com"", ""BusinessUnit"": ""Infrastructure"", ""ApplicationType"": ""Test"", ""Department"": ""Operations""}",,Unassigned,,Hours,RG-TEST-USE2 4 | aman.sharma@harvestingclouds.com,Aman Sharma,,0,aaaaaaaa-1111-1111-1111-aaaaaaaaaaa,Your-Subscription-Name,5/9/2018,1,1,2018,Data Transfer In - Zone 1,32c3ebec-1646-49e3-8127-2cafbd3a04d8,Networking,Networking,Zone 1,Data Transfer In (GB),1.547681,0,0,EastUS2,Microsoft.Compute,/subscriptions/aaaaaaaa-1111-1111-1111-aaaaaaaaaaa/resourceGroups/RG-TEST-USE2/providers/Microsoft.Compute/virtualMachines/VMName01,,,"{ ""ImageType"": """", ""ServiceType"": """", ""VMName"": """", ""VMProperties"": """", ""UsageType"": ""DataTrIn""}","{ ""ApplicationOwner"": ""aman@domain.com"", ""BusinessUnit"": ""Infrastructure"", ""ApplicationType"": ""Test"", ""Department"": ""Operations""}",,Unassigned,,GB,RG-TEST-USE2 5 | -------------------------------------------------------------------------------- /Scripts/Format-EABillingUsageCsvForTags/Output - UsageWithTags-2019-03-03-06-26.csv: -------------------------------------------------------------------------------- 1 | "AccountOwnerId","Account Name","ServiceAdministratorId","SubscriptionId","SubscriptionGuid","Subscription Name","Date","Month","Day","Year","Product","Meter ID","Meter Category","Meter Sub-Category","Meter Region","Meter Name","Consumed Quantity","ResourceRate","ExtendedCost","Resource Location","Consumed Service","Instance ID","ServiceInfo1","ServiceInfo2","AdditionalInfo","Tags","Store Service Identifier","Department Name","Cost Center","Unit Of Measure","Resource Group","ApplicationOwner","ApplicationType","BusinessUnit","Department" 2 | "aman.sharma@harvestingclouds.com","Aman Sharma","","0","aaaaaaaa-1111-1111-1111-aaaaaaaaaaa","Your-Subscription-Name","1/1/2018","1","1","2018","Data Transfer Out - Zone 1","9995d93a-7d35-4d3f-9c69-7a7fea447ef4","Networking","Networking","Zone 1","Data Transfer Out (GB)","0.004505","0.049998245","0.000225242","EastUS2","Microsoft.Compute","/subscriptions/aaaaaaaa-1111-1111-1111-aaaaaaaaaaa/resourceGroups/RG-TEST-USE2/providers/Microsoft.Compute/virtualMachines/VMName01","","","{ ""ImageType"": """", ""ServiceType"": """", ""VMName"": """", ""VMProperties"": """", ""UsageType"": ""DataTrOut""}","{ ""ApplicationOwner"": ""aman@domain.com"", ""BusinessUnit"": ""Infrastructure"", ""ApplicationType"": ""Test"", ""Department"": ""Operations""}","","Unassigned","","GB","RG-TEST-USE2","aman@domain.com","Test","Infrastructure","Operations" 3 | "aman.sharma@harvestingclouds.com","Aman Sharma","","0","aaaaaaaa-1111-1111-1111-aaaaaaaaaaa","Your-Subscription-Name","5/9/2018","1","1","2018","BASIC.A2 VM (Windows) - US East 2","f1cba056-ef57-4ce1-831b-b67168724adb","Virtual Machines","BASIC.A2 VM (Windows)","US East 2","Compute Hours","1","0.09","0.09","EastUS2","Microsoft.Compute","/subscriptions/aaaaaaaa-1111-1111-1111-aaaaaaaaaaa/resourceGroups/RG-TEST-USE2/providers/Microsoft.Compute/virtualMachines/VMName01","","","{ ""ImageType"": """", ""ServiceType"": ""Basic_A2"", ""VMName"": """", ""VMProperties"": """", ""UsageType"": ""ComputeHR""}","{ ""ApplicationOwner"": ""aman@domain.com"", ""BusinessUnit"": ""Infrastructure"", ""ApplicationType"": ""Test"", ""Department"": ""Operations""}","","Unassigned","","Hours","RG-TEST-USE2","aman@domain.com","Test","Infrastructure","Operations" 4 | "aman.sharma@harvestingclouds.com","Aman Sharma","","0","aaaaaaaa-1111-1111-1111-aaaaaaaaaaa","Your-Subscription-Name","5/9/2018","1","1","2018","Data Transfer In - Zone 1","32c3ebec-1646-49e3-8127-2cafbd3a04d8","Networking","Networking","Zone 1","Data Transfer In (GB)","1.547681","0","0","EastUS2","Microsoft.Compute","/subscriptions/aaaaaaaa-1111-1111-1111-aaaaaaaaaaa/resourceGroups/RG-TEST-USE2/providers/Microsoft.Compute/virtualMachines/VMName01","","","{ ""ImageType"": """", ""ServiceType"": """", ""VMName"": """", ""VMProperties"": """", ""UsageType"": ""DataTrIn""}","{ ""ApplicationOwner"": ""aman@domain.com"", ""BusinessUnit"": ""Infrastructure"", ""ApplicationType"": ""Test"", ""Department"": ""Operations""}","","Unassigned","","GB","RG-TEST-USE2","aman@domain.com","Test","Infrastructure","Operations" 5 | -------------------------------------------------------------------------------- /Scripts/Get-AzResourceInfo-VMsAndAllRelatedDisks/Get-AzResourceInfo-VMsAndAllRelatedDisks.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | File: Get-AzResourceInfo-VMsAndAllRelatedDisks.ps1 5 | 6 | Purpose: To get the report of all the VM resources and related OS and data disks in Azure in a specific Resource Group 7 | 8 | Version: 1.0.0.0 9 | 10 | Author: Aman Sharma 11 | ============================================================================================== 12 | .SYNOPSIS 13 | Azure Resources Report Generation Script for a specific Resource Group 14 | 15 | .DESCRIPTION 16 | This script is used to get the report for all the VM resources and related OS and data disks in Azure in a specific Resource Group. 17 | 18 | .EXAMPLE 19 | C:\PS> .\Get-AzResourceInfo-VMsAndAllRelatedDisks.ps1 20 | 21 | Description 22 | ----------- 23 | This command executes the script with default parameters. 24 | 25 | .INPUTS 26 | None. 27 | 28 | .OUTPUTS 29 | CSV file. 30 | 31 | .LINK 32 | None. 33 | #> 34 | 35 | #Input 36 | #Empty 37 | 38 | #Output Path variable to the CSV file. This file will be created. IT should not be present. Only the path should be present. 39 | $PathToOutputCSVReport = "D:\DATA\Scripts\Resource reports\ResourceReportVMAndDisks.csv" 40 | 41 | #Adding Azure Account and Subscription 42 | $env = Get-AzEnvironment -Name "AzureCloud" 43 | Connect-AzAccount -Environment $env 44 | 45 | #Creating Output Object 46 | $results = @() 47 | 48 | #Get all subscriptions 49 | $allSubscriptions = Get-AzSubscription 50 | 51 | foreach($currentSubscription in $allSubscriptions) 52 | { 53 | #Selecting current subscription 54 | Select-AzSubscription -SubscriptionId $currentSubscription.Id 55 | 56 | #Selecting all RGs 57 | #You can also specify filters here e.g. add some string before * to filter RGs that begins with that specific text. 58 | $allFilteredRGs = Get-AzResourceGroup -Name "*" 59 | 60 | foreach($currentRG in $allFilteredRGs) 61 | { 62 | #Fetch all resources in the RG 63 | $resources = Get-AzResource -ResourceGroupName $currentRG.ResourceGroupName 64 | 65 | foreach($resource in $resources) 66 | { 67 | #Declaring Variables 68 | $vmSize = "" 69 | $name = $resource.Name 70 | $diskSize = "" 71 | $diskType = "" 72 | $attachedToVM = "" 73 | $LUNNumber = "" 74 | $osType = "" 75 | $osDiskName = "" 76 | $osDiskSize = "" 77 | $osDiskType = "" 78 | $dataDiskName = "" 79 | $dataDiskSize = "" 80 | $dataDiskType = "" 81 | $dataDiskLUN = "" 82 | $dataDiskType = "" 83 | 84 | if($resource.Type -eq "Microsoft.Compute/virtualMachines") 85 | { 86 | #Write-Output "VM Found" 87 | # 1. VM 88 | $vm = Get-AzVM -Name $resource.Name -ResourceGroupName $resource.ResourceGroupName 89 | $vmSize = $vm.HardwareProfile.VmSize 90 | $attachedToVM = $vm.Name 91 | $storageProfile = $vm.StorageProfile 92 | $osType = $storageProfile.OsDisk.OsType 93 | 94 | #region Adding VM details to results 95 | $details = @{ 96 | Name = $resource.Name 97 | OsType = $osType 98 | ResourceId = $resource.ResourceId 99 | ResourceType = $resource.ResourceType 100 | OSOrDataDisk = "" 101 | ResourceGroupName =$resource.ResourceGroupName 102 | Location = $resource.Location 103 | SubscriptionId = $currentSubscription.Id 104 | SubscriptionName = $currentSubscription.Name 105 | Sku = $resource.Sku.Name 106 | VMSize = $vmSize 107 | diskSize = $diskSize 108 | diskType = $diskType 109 | attachedToVM = $attachedToVM 110 | LUNNumber = $LUNNumber 111 | Caching = "" 112 | WriteAcceleratorEnabled = "" 113 | } 114 | $results += New-Object PSObject -Property $details 115 | #endregion 116 | 117 | # 2 OS Disk 118 | #OS Disk Info 119 | $osDiskName = $storageProfile.OsDisk.Name 120 | $osDiskSize = $storageProfile.OsDisk.DiskSizeGB 121 | $osDiskType = $storageProfile.OsDisk.ManagedDisk.StorageAccountType 122 | $osDiskCaching = $storageProfile.OsDisk.Caching 123 | $osDiskWriteAcceleratorEnabled = $storageProfile.OsDisk.WriteAcceleratorEnabled 124 | 125 | 126 | #region Adding OS Disk details to results 127 | $details = @{ 128 | Name = $osDiskName 129 | OsType = $osType 130 | ResourceId = "" 131 | ResourceType = "Microsoft.Compute/disks" 132 | OSOrDataDisk = "OS Disk" 133 | ResourceGroupName =$resource.ResourceGroupName 134 | Location = $resource.Location 135 | SubscriptionId = $currentSubscription.Id 136 | SubscriptionName = $currentSubscription.Name 137 | Sku = $resource.Sku.Name 138 | VMSize = $vmSize 139 | diskSize = $osDiskSize 140 | diskType = $osDiskType 141 | attachedToVM = $attachedToVM 142 | LUNNumber = $LUNNumber 143 | Caching = $osDiskCaching 144 | WriteAcceleratorEnabled = $osDiskWriteAcceleratorEnabled 145 | } 146 | $results += New-Object PSObject -Property $details 147 | #endregion 148 | 149 | # 3 Data Disks 150 | #Data Disks 151 | $dataDisks = $storageProfile.DataDisks 152 | 153 | foreach ($dataDisk in $dataDisks) 154 | { 155 | $dataDiskName = $dataDisk.Name 156 | $dataDiskSize = $dataDisk.DiskSizeGB 157 | $dataDiskType = $dataDisk.OsDisk.ManagedDisk.StorageAccountType 158 | $dataDiskLUN = $dataDisk.Lun 159 | $dataDiskCaching = $dataDisk.Caching 160 | $dataDiskWriteAcceleratorEnabled = $dataDisk.WriteAcceleratorEnabled 161 | 162 | $diskDetails = Get-AzDisk -ResourceGroupName $resource.ResourceGroupName -DiskName $dataDiskName 163 | $dataDiskType = $diskDetails.Sku.Name 164 | 165 | #region Adding Data Disk details to results 166 | $details = @{ 167 | Name = $dataDiskName 168 | OsType = $osType 169 | ResourceId = "" 170 | ResourceType = "Microsoft.Compute/disks" 171 | OSOrDataDisk = "Data Disk" 172 | ResourceGroupName =$resource.ResourceGroupName 173 | Location = $resource.Location 174 | SubscriptionId = $currentSubscription.Id 175 | SubscriptionName = $currentSubscription.Name 176 | Sku = $resource.Sku.Name 177 | VMSize = $vmSize 178 | diskSize = $dataDiskSize 179 | diskType = $dataDiskType 180 | attachedToVM = $attachedToVM 181 | LUNNumber = $dataDiskLUN 182 | Caching = $dataDiskCaching 183 | WriteAcceleratorEnabled = $dataDiskWriteAcceleratorEnabled 184 | } 185 | $results += New-Object PSObject -Property $details 186 | #endregion 187 | } 188 | } 189 | } 190 | } 191 | } 192 | 193 | #Exporting to CSV 194 | $results | export-csv -Path $PathToOutputCSVReport -NoTypeInformation 195 | -------------------------------------------------------------------------------- /Scripts/Get-AzResourceInfo-VMsAndAllRelatedDisks/SAMPLE OUTPUT - ResourceReportVMAndDisks.csv: -------------------------------------------------------------------------------- 1 | Name,attachedToVM,VMSize,OSOrDataDisk,Sku,LUNNumber,OsType,diskType,ResourceGroupName,diskSize,SubscriptionName,Location,ResourceType,SubscriptionId,Caching,WriteAcceleratorEnabled 2 | Accounts101,Accounts101,Standard_D2as_v4,,,,Windows,,RG101,,Visual Studio Enterprise,eastus,Microsoft.Compute/virtualMachines,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,, 3 | Accounts101_Accounts101,Accounts101,Standard_D2as_v4,OS Disk,,,Windows,,RG101,127,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,ReadWrite, 4 | Accounts101_Disk101,Accounts101,Standard_D2as_v4,Data Disk,,0,Windows,Premium_LRS,RG101,4,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,None,FALSE 5 | Accounts102,Accounts102,Standard_B2ms,,,,Windows,,RG101,,Visual Studio Enterprise,eastus,Microsoft.Compute/virtualMachines,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,, 6 | Accounts102_OsDisk_1_1e8af287e75d4a408cc1c5d8c2b972c9,Accounts102,Standard_B2ms,OS Disk,,,Windows,Standard_LRS,RG101,127,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,ReadWrite, 7 | Accounts102_Data01,Accounts102,Standard_B2ms,Data Disk,,0,Windows,Premium_LRS,RG101,4,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,None,FALSE 8 | Accounts102_Data02,Accounts102,Standard_B2ms,Data Disk,,1,Windows,Premium_LRS,RG101,4,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,None,FALSE 9 | indiavm01,indiavm01,Standard_D2s_v3,,,,Windows,,RG-Secondary,,Visual Studio Enterprise,centralindia,Microsoft.Compute/virtualMachines,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,, 10 | indiavm01_OsDisk_1_8e1960eefbdd46f5a238851bfcc11b6d,indiavm01,Standard_D2s_v3,OS Disk,,,Windows,,RG-Secondary,127,Visual Studio Enterprise,centralindia,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,ReadWrite, 11 | DevVm102,DevVm102,Standard_D2s_v3,,,,Windows,,RG102,,Visual Studio Enterprise,eastus,Microsoft.Compute/virtualMachines,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,, 12 | DevVm102_disk1_e3a24711c8724e488e0f162fd7666a15,DevVm102,Standard_D2s_v3,OS Disk,,,Windows,,RG102,127,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,ReadWrite, 13 | DevVM101,DevVM101,Standard_D2s_v3,,,,Windows,,RG102,,Visual Studio Enterprise,eastus,Microsoft.Compute/virtualMachines,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,, 14 | DevVM101_OsDisk_1_1ba317f166b94311bedaf2eac6dadc40,DevVM101,Standard_D2s_v3,OS Disk,,,Windows,,RG102,127,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,ReadWrite, 15 | DevDataDisk01,DevVM101,Standard_D2s_v3,Data Disk,,0,Windows,Standard_LRS,RG102,4,Visual Studio Enterprise,eastus,Microsoft.Compute/disks,aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb,None,FALSE 16 | -------------------------------------------------------------------------------- /Scripts/Get-AzResourceInfo-VMsAndAllRelatedDisks/SAMPLE REPORT - ResourceReportVMAndDisks.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HarvestingClouds/PowerShellSamples/8d8a2f006c96cf240830a1cb4d38f45fa920501a/Scripts/Get-AzResourceInfo-VMsAndAllRelatedDisks/SAMPLE REPORT - ResourceReportVMAndDisks.xlsx -------------------------------------------------------------------------------- /Scripts/Get-AzureRmResourceReport/Get-AzureRmAllResourceReport.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Microsoft Corporation. All rights reserved. 5 | 6 | File: Get-AzureRmAllResourcesReport.ps1 7 | 8 | Purpose: To get the report of all the resources in Azure 9 | 10 | Version: 1.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Azure Resources Tags Report Generation Script 16 | 17 | .DESCRIPTION 18 | This script is used to get the report for all the resources in Azure. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Get-AzureRmAllResourcesReport.ps1 22 | 23 | Description 24 | ----------- 25 | This command executes the script with default parameters. 26 | 27 | .INPUTS 28 | None. 29 | 30 | .OUTPUTS 31 | None. 32 | 33 | .LINK 34 | None. 35 | #> 36 | 37 | #Path variable to the Output CSV file 38 | $PathToOutputCSVReport = "C:\DATA\ResourceReport.csv" 39 | 40 | #Adding Azure Account and Subscription 41 | Add-AzureRmAccount 42 | 43 | #Getting all Azure Subscriptions 44 | $subs = Get-AzureRmSubscription 45 | 46 | #Checking if the subscriptions are found or not 47 | if(($subs -ne $null) -or ($subs.Count -gt 0)) 48 | { 49 | #Creating Output Object 50 | $results = @() 51 | 52 | #Iterating over various subscriptions 53 | foreach($sub in $subs) 54 | { 55 | $SubscriptionId = $sub.SubscriptionId 56 | #Selecting the Azure Subscription 57 | Select-AzureRmSubscription -SubscriptionId $SubscriptionId 58 | 59 | #Getting all Azure Resources 60 | $resources = Get-AzureRmResource 61 | 62 | foreach($resource in $resources) 63 | { 64 | #Declaring Variables 65 | $TagsAsString = "" 66 | $ApplicationOwner = "" 67 | $ApplicationType = "" 68 | $CostCenter = "" 69 | $Department = "" 70 | $BuildDate = "" 71 | $ApplicationCategory = "" 72 | $vmSize = "" 73 | $sqlTier = "" 74 | $sqlCapacity = "" 75 | $name = $resource.Name 76 | 77 | if($resource.Type -eq "Microsoft.Compute/virtualMachines") 78 | { 79 | $vm = Get-AzureRmVM -Name $resource.Name -ResourceGroupName $resource.ResourceGroupName 80 | $vmSize = $vm.HardwareProfile.VmSize 81 | } 82 | 83 | elseif($resource.Type -eq "Microsoft.Sql/servers/databases") 84 | { 85 | $sql = Get-AzureRmResource -ResourceGroupName $resource.ResourceGroupName -ResourceType Microsoft.Sql/servers/databases -ResourceName "$name" -ApiVersion 2017-10-01-preview 86 | $sqlTier = $sql.Sku.tier 87 | $sqlCapacity = $sql.Sku.capacity 88 | } 89 | elseif($resource.Type -eq "Microsoft.Compute/disks") 90 | { 91 | $disk = Get-AzureRmResource -ResourceGroupName $resource.ResourceGroupName -ResourceType "Microsoft.Compute/disks" -ResourceName "$name" -ApiVersion 2017-10-01-preview 92 | } 93 | 94 | 95 | 96 | 97 | #Fetching Tags 98 | $Tags = $resource.Tags 99 | 100 | #Adding to Results 101 | $details = @{ 102 | Name = $resource.Name 103 | ResourceId = $resource.ResourceId 104 | ResourceName = $resource.ResourceName 105 | ResourceType = $resource.ResourceType 106 | ResourceGroupName =$resource.ResourceGroupName 107 | Location = $resource.Location 108 | SubscriptionId = $sub.SubscriptionId 109 | SubscriptionName = $sub.Name 110 | Sku = $resource.Sku 111 | VMSize = $vmSize 112 | sqltier = $sqlTier 113 | sqlCapacity = $sqlCapacity 114 | Tags = $Tags 115 | } 116 | $results += New-Object PSObject -Property $details 117 | } 118 | } 119 | 120 | $results | export-csv -Path $PathToOutputCSVReport -NoTypeInformation 121 | } 122 | else 123 | { 124 | Write-Host -ForegroundColor Red "No Subscription Found" 125 | } 126 | -------------------------------------------------------------------------------- /Scripts/Get-AzureRmResourceReport/Get-AzureRmResourceReportForOneResourceGroup.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Microsoft Corporation. All rights reserved. 5 | 6 | File: Get-AzureRmResourceReportForOneResourceGroup.ps1 7 | 8 | Purpose: To get the report of all the resources in Azure 9 | 10 | Version: 1.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Azure Resources Tags Report Generation Script 16 | 17 | .DESCRIPTION 18 | This script is used to get the report for all the resources in a Resource Group in Azure. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Get-AzureRmResourceReportForOneResourceGroup.ps1 22 | 23 | Description 24 | ----------- 25 | This command executes the script with default parameters. 26 | 27 | .INPUTS 28 | None. 29 | 30 | .OUTPUTS 31 | None. 32 | 33 | .LINK 34 | None. 35 | #> 36 | 37 | #Input 38 | $ResourceGroupNameString = "test-rg" 39 | 40 | #Path variable to the CSV file 41 | $PathToOutputCSVReport = "C:\DATA\ResourceReport.csv" 42 | 43 | #Adding Azure Account and Subscription 44 | Add-AzureRmAccount 45 | 46 | #Getting all Azure Subscriptions 47 | $subs = Get-AzureRmSubscription 48 | 49 | #Checking if the subscriptions are found or not 50 | if(($subs -ne $null) -or ($subs.Count -gt 0)) 51 | { 52 | #Creating Output Object 53 | $results = @() 54 | 55 | #Iterating over various subscriptions 56 | foreach($sub in $subs) 57 | { 58 | $SubscriptionId = $sub.SubscriptionId 59 | #Selecting the Azure Subscription 60 | Select-AzureRmSubscription -SubscriptionId $SubscriptionId 61 | 62 | #Getting all Azure Resources 63 | $resources = Get-AzureRmResource 64 | 65 | foreach($resource in $resources) 66 | { 67 | if($resource.ResourceGroupName -like "*$ResourceGroupNameString*") 68 | { 69 | #Declaring Variables 70 | $TagsAsString = "" 71 | $ApplicationOwner = "" 72 | $ApplicationType = "" 73 | $CostCenter = "" 74 | $Department = "" 75 | $BuildDate = "" 76 | $ApplicationCategory = "" 77 | $vmSize = "" 78 | $sqlTier = "" 79 | $sqlCapacity = "" 80 | $name = $resource.Name 81 | 82 | if($resource.Type -eq "Microsoft.Compute/virtualMachines") 83 | { 84 | $vm = Get-AzureRmVM -Name $resource.Name -ResourceGroupName $resource.ResourceGroupName 85 | $vmSize = $vm.HardwareProfile.VmSize 86 | } 87 | 88 | elseif($resource.Type -eq "Microsoft.Sql/servers/databases") 89 | { 90 | $sql = Get-AzureRmResource -ResourceGroupName $resource.ResourceGroupName -ResourceType Microsoft.Sql/servers/databases -ResourceName "$name" -ApiVersion 2017-10-01-preview 91 | $sqlTier = $sql.Sku.tier 92 | $sqlCapacity = $sql.Sku.capacity 93 | } 94 | elseif($resource.Type -eq "Microsoft.Compute/disks") 95 | { 96 | $disk = Get-AzureRmResource -ResourceGroupName $resource.ResourceGroupName -ResourceType "Microsoft.Compute/disks" -ResourceName "$name" -ApiVersion 2017-10-01-preview 97 | } 98 | 99 | 100 | 101 | 102 | #Fetching Tags 103 | $Tags = $resource.Tags 104 | 105 | #Adding to Results 106 | $details = @{ 107 | Name = $resource.Name 108 | ResourceId = $resource.ResourceId 109 | ResourceName = $resource.ResourceName 110 | ResourceType = $resource.ResourceType 111 | ResourceGroupName =$resource.ResourceGroupName 112 | Location = $resource.Location 113 | SubscriptionId = $sub.SubscriptionId 114 | SubscriptionName = $sub.Name 115 | Sku = $resource.Sku 116 | VMSize = $vmSize 117 | sqltier = $sqlTier 118 | sqlCapacity = $sqlCapacity 119 | Tags = $Tags 120 | } 121 | $results += New-Object PSObject -Property $details 122 | } 123 | } 124 | } 125 | 126 | $results | export-csv -Path $PathToOutputCSVReport -NoTypeInformation 127 | } 128 | else 129 | { 130 | Write-Host -ForegroundColor Red "No Subscription Found" 131 | } 132 | -------------------------------------------------------------------------------- /Scripts/Get-AzureRmTagsReport.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Harvesting Clouds. All rights reserved. 5 | 6 | File: Get-AzureRmTagsReport.ps1 7 | 8 | Purpose: To get the report for tags of all the resources in Azure 9 | 10 | Version: 1.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Azure Resources Tags Report Generation Script 16 | 17 | .DESCRIPTION 18 | This script is used to get the report for tags of all the resources in Azure. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Get-AzureRmVMDiskDetails.ps1 -SubscriptionName "Your-Subscription-Name-Here" -OutputPath "C:\AzureData\TagsResults" 22 | 23 | Description 24 | ----------- 25 | This command executes the script with default parameters. Replace the value for SubscriptionName parameter as per your environment. Also replace the output path as per your environment. The script will prompt for Azure Credentials. It doesn't store these credentials anywhere. 26 | 27 | .PARAMETER SubscriptionName 28 | This is the name of the subscription for which you want the report. 29 | 30 | .PARAMETER OutputPath 31 | This is the output directory path where you want to save the report. 32 | 33 | .INPUTS 34 | None. 35 | 36 | .OUTPUTS 37 | None. 38 | 39 | .LINK 40 | None. 41 | #> 42 | 43 | param 44 | ( 45 | [Parameter(Mandatory=$True)] 46 | [string]$SubscriptionName, 47 | 48 | [Parameter(Mandatory=$True)] 49 | [string]$OutputPath 50 | 51 | ) 52 | 53 | try 54 | { 55 | #Adding Azure Account and Subscription 56 | Add-AzureRmAccount 57 | 58 | #Selecting the Azure Subscription 59 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 60 | 61 | #Getting all Azure Resources 62 | $resources = Get-AzureRmResource 63 | 64 | #Declaring Variables 65 | $results = @() 66 | $TagsAsString = "" 67 | 68 | foreach($resource in $resources) 69 | { 70 | #Fetching Tags 71 | $Tags = $resource.Tags 72 | 73 | #Checkign if tags is null or have value 74 | if($Tags -ne $null) 75 | { 76 | 77 | $Tags.GetEnumerator() | % { $TagsAsString += $_.Key + ":" + $_.Value + ";" } 78 | } 79 | else 80 | { 81 | $TagsAsString = "NULL" 82 | } 83 | #$results = @() 84 | #Adding to Results 85 | $details = @{ 86 | Tags = $TagsAsString 87 | Name = $resource.Name 88 | ResourceId = $resource.ResourceId 89 | ResourceName = $resource.ResourceName 90 | ResourceType = $resource.ResourceType 91 | ResourceGroupName =$resource.ResourceGroupName 92 | Location = $resource.Location 93 | SubscriptionId = $resource.SubscriptionId 94 | Sku = $resource.Sku 95 | } 96 | $results += New-Object PSObject -Property $details 97 | 98 | #Clearing Variable 99 | $TagsAsString = "" 100 | } 101 | 102 | #Generating Output 103 | $OutputPathWithFileName = $OutputPath + "\Tags-" + $SubscriptionName + ".csv" 104 | $results | export-csv -Path $OutputPathWithFileName -NoTypeInformation 105 | } 106 | catch [system.exception] 107 | { 108 | Write-Output "Error in generating report: $($_.Exception.Message) " 109 | Write-Output "Error Details are: " 110 | Write-Output $Error[0].ToString() 111 | Exit $ERRORLEVEL 112 | } 113 | -------------------------------------------------------------------------------- /Scripts/Get-AzureSQLDatabases/Get-AzureSQLDatabases.ps1: -------------------------------------------------------------------------------- 1 | #Logging into Azure 2 | #Login-AzureRmAccount 3 | 4 | $OutFileLocation='D:\Data\temp' 5 | try 6 | { 7 | $subscriptions=Get-AzureRmSubscription 8 | 9 | #output object 10 | $objects = @() 11 | 12 | #iterating subscriptions 13 | foreach ($subscription in $subscriptions) 14 | { 15 | #selecting subscription 16 | Select-AzureRmSubscription -Subscription $subscription.Id 17 | 18 | #Getting all sql resources 19 | $resources = Get-AzureRmResource | ?{ $_.kind -eq "v12.0,user" } | select resourcename,resourceid 20 | 21 | #iterating sql resources 22 | foreach($resource in $resources) 23 | { 24 | $resourceGroupName = $resource.ResourceId.Split('/')[4] 25 | $serverName = $resource.ResourceId.Split('/')[8] 26 | $databaseName = $resource.ResourceId.Split('/')[10] 27 | 28 | $sqlDatabases = Get-AzureRmSqlDatabase -DatabaseName $databaseName -ServerName $servername -ResourceGroupName $resourceGroupName 29 | 30 | $objects += New-Object -Type PSObject -Prop @{'ResourceGroupName'=$resourceGroupName;'ServerName'=$serverName;'DatabaseName'=$databaseName;'SkuName'=$sqlDatabases.SkuName;'Status'=$sqlDatabases.Status; 'MaxSizeBytes'=$sqlDatabases.MaxSizeBytes} 31 | } 32 | 33 | } 34 | $objects|export-csv -NoTypeInformation ($OutFileLocation + '\' + (get-date -format yyyy-MM-dd) + '_SQLDatabases.csv') 35 | } 36 | 37 | catch 38 | { 39 | throw $Error[0].Exception.Message 40 | } 41 | -------------------------------------------------------------------------------- /Scripts/Get-IsElevated/Get-IsElevated.ps1: -------------------------------------------------------------------------------- 1 | #region - Script Functions 2 | <# 3 | ============================================================================================== 4 | Script Functions 5 | Get-IsElevated - Checks if the script is in an elevated PS session 6 | ============================================================================================== 7 | #> 8 | function Get-IsElevated 9 | { 10 | # Get the ID and security principal of the current user account 11 | $WindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent() 12 | $WindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($WindowsID) 13 | 14 | # Get the security principal for the Administrator role 15 | $adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator 16 | 17 | # Check to see if currently running "as Administrator" 18 | if ($WindowsPrincipal.IsInRole($adminRole)) 19 | { 20 | return $True 21 | } 22 | else 23 | { 24 | return $False 25 | } 26 | } 27 | 28 | #endregion 29 | 30 | #region - Script Control Routine 31 | Start-Transcript $ScriptLog 32 | Write-Verbose "======================================================================" 33 | Write-Verbose "Script Started." 34 | 35 | if(Get-IsElevated) 36 | { 37 | try 38 | { 39 | # Insert code for elevated execution 40 | (Get-Host).UI.RawUI.WindowTitle = "$env:USERDOMAIN\$env:USERNAME (Elevated)" 41 | Write-Verbose "Script is running in an elevated PowerShell host. " 42 | 43 | 44 | #TODO - The Main Code will come here 45 | } 46 | catch [system.exception] 47 | { 48 | Write-Verbose "Script Error: $($_.Exception.Message) " 49 | Write-Verbose "Error Details are: " 50 | Write-Verbose $Error[0].ToString() 51 | Stop-Transcript 52 | 53 | Exit 54 | } 55 | } 56 | else 57 | { 58 | # Insert code for non-elevated execution 59 | (Get-Host).UI.RawUI.WindowTitle = "$env:USERDOMAIN\$env:USERNAME (Not Elevated)" 60 | Write-Verbose "Please start the script from an elevated PowerShell host. " 61 | Stop-Transcript 62 | Exit 63 | } 64 | Write-Verbose "Script Completed. " 65 | Write-Verbose "======================================================================" 66 | Stop-Transcript 67 | #endregion -------------------------------------------------------------------------------- /Scripts/Get-PendingReboot/Get-PendingReboot.ps1: -------------------------------------------------------------------------------- 1 | Function Get-PendingReboot 2 | { 3 | <# 4 | This will query the local machine for pending reboot information. 5 | 6 | .EXAMPLE 7 | C:\Users\aman\Downloads> import-module .\Get-PendingReboot.ps1 8 | C:\Users\aman\Downloads> $Servers = Get-Content C:\Users\aman\Downloads\Servers.txt 9 | C:\Users\aman\Downloads> Get-PendingReboot -Computer $Servers | Export-Csv C:\Users\aman\Downloads\PendingRebootReport.csv -NoTypeInformation 10 | 11 | or for interactive in the powershell windows view (this view will display the file name pending rename ) 12 | 13 | .EXAMPLE 14 | C:\Users\aman\Downloads> import-module .\Get-PendingReboot.ps1 15 | C:\Users\aman\Downloads> $Servers = Get-Content C:\Users\aman\Downloads\Servers.txt 16 | C:\Users\aman\Downloads> Get-PendingReboot -Computer $Servers 17 | 18 | #> 19 | 20 | [CmdletBinding()] 21 | param( 22 | [Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 23 | [Alias("CN","Computer")] 24 | [String[]]$ComputerName="$env:COMPUTERNAME", 25 | [String]$ErrorLog 26 | ) 27 | 28 | Begin { }## End Begin Script Block 29 | Process { 30 | Foreach ($Computer in $ComputerName) { 31 | Try { 32 | ## Setting pending values to false to cut down on the number of else statements 33 | $CompPendRen,$PendFileRename,$Pending,$SCCM = $false,$false,$false,$false 34 | 35 | ## Setting CBSRebootPend to null since not all versions of Windows has this value 36 | $CBSRebootPend = $null 37 | 38 | ## Querying WMI for build version 39 | $WMI_OS = Get-WmiObject -Class Win32_OperatingSystem -Property BuildNumber, CSName -ComputerName $Computer -ErrorAction Stop 40 | 41 | ## Making registry connection to the local/remote computer 42 | $HKLM = [UInt32] "0x80000002" 43 | $WMI_Reg = [WMIClass] "\\$Computer\root\default:StdRegProv" 44 | 45 | 46 | ## If Vista/2008 & Above query the CBS Reg Key 47 | If ([Int32]$WMI_OS.BuildNumber -ge 6001) { 48 | $RegSubKeysCBS = $WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\") 49 | $CBSRebootPend = $RegSubKeysCBS.sNames -contains "RebootPending" 50 | 51 | } 52 | 53 | ## Query WUAU from the registry 54 | $RegWUAURebootReq = $WMI_Reg.EnumKey($HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\") 55 | $WUAURebootReq = $RegWUAURebootReq.sNames -contains "RebootRequired" 56 | 57 | ## Query PendingFileRenameOperations from the registry 58 | $RegSubKeySM = $WMI_Reg.GetMultiStringValue($HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\","PendingFileRenameOperations") 59 | $RegValuePFRO = $RegSubKeySM.sValue 60 | 61 | ## Query JoinDomain key from the registry - These keys are present if pending a reboot from a domain join operation 62 | $Netlogon = $WMI_Reg.EnumKey($HKLM,"SYSTEM\CurrentControlSet\Services\Netlogon").sNames 63 | $PendDomJoin = ($Netlogon -contains 'JoinDomain') -or ($Netlogon -contains 'AvoidSpnSet') 64 | 65 | ## Query ComputerName and ActiveComputerName from the registry 66 | $ActCompNm = $WMI_Reg.GetStringValue($HKLM,"SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\","ComputerName") 67 | $CompNm = $WMI_Reg.GetStringValue($HKLM,"SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName\","ComputerName") 68 | 69 | If (($ActCompNm -ne $CompNm) -or $PendDomJoin) { 70 | $CompPendRen = $true 71 | } 72 | 73 | ## If PendingFileRenameOperations has a value set $RegValuePFRO variable to $true 74 | If ($RegValuePFRO) { 75 | $PendFileRename = $true 76 | } 77 | 78 | ## Determine SCCM 2012 Client Reboot Pending Status 79 | ## To avoid nested 'if' statements and unneeded WMI calls to determine if the CCM_ClientUtilities class exist, setting EA = 0 80 | $CCMClientSDK = $null 81 | $CCMSplat = @{ 82 | NameSpace='ROOT\ccm\ClientSDK' 83 | Class='CCM_ClientUtilities' 84 | Name='DetermineIfRebootPending' 85 | ComputerName=$Computer 86 | ErrorAction='Stop' 87 | } 88 | ## Try CCMClientSDK 89 | Try { 90 | $CCMClientSDK = Invoke-WmiMethod @CCMSplat 91 | } Catch [System.UnauthorizedAccessException] { 92 | $CcmStatus = Get-Service -Name CcmExec -ComputerName $Computer -ErrorAction SilentlyContinue 93 | If ($CcmStatus.Status -ne 'Running') { 94 | Write-Warning "$Computer`: Error - CcmExec service is not running." 95 | $CCMClientSDK = $null 96 | } 97 | } Catch { 98 | $CCMClientSDK = $null 99 | } 100 | 101 | If ($CCMClientSDK) { 102 | If ($CCMClientSDK.ReturnValue -ne 0) { 103 | Write-Warning "Error: DetermineIfRebootPending returned error code $($CCMClientSDK.ReturnValue)" 104 | } 105 | If ($CCMClientSDK.IsHardRebootPending -or $CCMClientSDK.RebootPending) { 106 | $SCCM = $true 107 | } 108 | } 109 | 110 | Else { 111 | $SCCM = $null 112 | } 113 | 114 | ## Creating Custom PSObject and Select-Object Splat 115 | $SelectSplat = @{ 116 | Property=( 117 | 'Computer', 118 | 'CBServicing', 119 | 'WindowsUpdate', 120 | 'CCMClientSDK', 121 | 'PendComputerRename', 122 | 'PendFileRename', 123 | 'PendFileRenVal', 124 | 'RebootPending' 125 | )} 126 | New-Object -TypeName PSObject -Property @{ 127 | Computer=$WMI_OS.CSName 128 | CBServicing=$CBSRebootPend 129 | WindowsUpdate=$WUAURebootReq 130 | CCMClientSDK=$SCCM 131 | PendComputerRename=$CompPendRen 132 | PendFileRename=$PendFileRename 133 | PendFileRenVal=$RegValuePFRO 134 | RebootPending=($CompPendRen -or $CBSRebootPend -or $WUAURebootReq -or $SCCM -or $PendFileRename) 135 | } | Select-Object @SelectSplat 136 | 137 | } Catch { 138 | Write-Warning "$Computer`: $_" 139 | ## If $ErrorLog, log the file to a user specified location/path 140 | If ($ErrorLog) { 141 | Out-File -InputObject "$Computer`,$_" -FilePath $ErrorLog -Append 142 | } 143 | } 144 | }## End Foreach ($Computer in $ComputerName) 145 | }## End Process 146 | 147 | End { }## End End 148 | 149 | }## End Function Get-PendingReboot -------------------------------------------------------------------------------- /Scripts/Get-SSPSync/SSPSyncProcess.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [parameter(Mandatory = $true)] 3 | [String]$SqlServer, 4 | [parameter(Mandatory = $true)] 5 | [String]$Database 6 | ) 7 | 8 | #$SubscriptionID = "adf124da-c139-44c5-b226-3a812fbe6cf0" #DEV 9 | #$SubscriptionID = "f1e34301-c396-4b15-9f25-cab99b61ce7a" #HUB 10 | #$SubscriptionID = "9fa297b7-731b-4d35-b494-e2b65749f1b7" #PRD 11 | #$SubscriptionID = "dc212303-893e-404d-a787-3a960b14e8bf" #TST 12 | 13 | $connectionName = "AzureRunAsConnection" 14 | $Role = "Virtual Machine Operator" 15 | $Scope = "VirtualMachine" 16 | $SqlCred = Get-AutomationPSCredential -Name 'SSPAzureSQLServerAccount' 17 | #$RecordsPerBatch = 10 18 | $InitialExecutionDatetime = (Get-Date) 19 | $RetunrObjItm = new-object PSObject 20 | $DefaultRoleUserDisplayName = "Freddy Mora Silva" 21 | $DefaultRoleUserSignInName = "freddy.silva@eversource.com" 22 | $SqlServerPort = "1433" 23 | $SqlUsername = $SqlCred.UserName 24 | $SqlPass = $SqlCred.GetNetworkCredential().Password 25 | $SQLConn = New-Object System.Data.SqlClient.SqlConnection("Server=tcp:$SqlServer,$SqlServerPort;Database=$Database;User ID=$SqlUsername;Password=$SqlPass;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;") 26 | 27 | # Open the SQL connection 28 | Write-output "Connecting to SQL Database" 29 | $SQLConn.Open() 30 | 31 | # Define the SQL command to run. In this case we are getting the number of rows in the table 32 | Write-output "Creating SQL Adapter, DataSet and Command Objects" 33 | 34 | $SqlAdapter = New-Object system.Data.SqlClient.SqlDataAdapter 35 | $Dataset = New-Object System.Data.DataSet 36 | $SqlCmd = New-Object System.Data.SqlClient.SqlCommand 37 | 38 | $SQLCmd.CommandTimeout = 120 39 | $SqlCmd.Connection = $SQLConn 40 | 41 | Write-output "Executing to get VMs Collection" 42 | 43 | $Dataset.Reset() 44 | $SqlQuery1 = "SELECT TOP 1 VMS.[RequestID],VMS.[AzureVMName],VMS.[Username],ST.StatusText,APR.ApproverName,BSS.BusinessUnitName,APT.AppTypeName,DPT.DepartmentName,VMS.[CostCenter],VMS.[OwnerDescription],ENV.EnvironmentName,REG.RegionName,NET.NetworkResourceGroupName,VRT.VirtualNetworkName,SNT.SubNetName FROM [dbo].[AzureVMs] VMS INNER JOIN RequestStatus ST On VMS.StatusID = ST.StatusID INNER JOIN Approvers APR On VMS.ApproverID = APR.ApproverID INNER JOIN BusinessUnits BSS On VMS.BusinessUnitID = BSS.BusinessUnitID INNER JOIN AppTypes APT On VMS.AppTypeID = APT.AppTypeID INNER JOIN Departments DPT On VMS.DepartmentID = DPT.DepartmentID INNER JOIN Environments ENV On VMS.EnvironmentID = ENV.EnvironmentID INNER JOIN Region REG On VMS.RegionID = REG.RegionID INNER JOIN NetworkResourceGroup NET On VMS.NetworkResourceGroupID = NET.NetworkResourceGroupID INNER JOIN VirtualNetwork VRT On VMS.VirtualNetworkID = VRT.VirtualNetworkID INNER JOIN SubNet SNT On VMS.SubNetID = SNT.SubNetID ORDER BY VMS.[RequestID] DESC" 45 | $SqlCmd.CommandText = $SqlQuery1 46 | $SqlAdapter.SelectCommand = $SqlCmd 47 | $SqlAdapter.Fill($Dataset) 48 | 49 | # Output the count 50 | $VMSTable = $Dataset.Tables[0] 51 | 52 | #Load Data in Array 53 | $VMSArray = @() 54 | $VMSArray = @($VMSTable) 55 | 56 | $CurrCount = $VMSArray.Count 57 | $CurrentVMCount = 0 58 | 59 | if ($CurrCount -gt 0) 60 | { 61 | $strCurrentVMCount = $VMSArray[0].RequestID 62 | $CurrentVMCount = [System.Int32]::Parse($strCurrentVMCount.Substring(10, 5)) 63 | } 64 | else 65 | { 66 | $CurrentVMCount = 0 67 | } 68 | 69 | Write-output "Current VM Count in Database is $CurrentVMCount" 70 | 71 | #Get Names Collection 72 | #Write-output "Get VM Names Collection" 73 | 74 | #$VMNames = $VMSArray | Foreach-Object {$_.AzureVMName} | Select -Unique 75 | 76 | #Get Current Resource Groups 77 | # Execute the SQL command 78 | Write-output "Getting NetWork Resource Groups from DB" 79 | 80 | $Dataset.Reset() 81 | $SqlQuery2 = "Select [NetworkResourceGroupName] from [dbo].[NetworkResourceGroup]" 82 | $SqlCmd.CommandText = $SqlQuery2 83 | $SqlAdapter.SelectCommand = $SqlCmd 84 | $SqlAdapter.Fill($Dataset) 85 | 86 | # Output the count 87 | $ResGroupsTable = $Dataset.Tables[0] 88 | 89 | #Load Data in Array 90 | $ResGroupsArray = @() 91 | $ResGroupsArray = @($ResGroupsTable) 92 | 93 | #$VMSArray 94 | 95 | #Get Names Collection 96 | Write-output "Get Resource Group Names Collection" 97 | 98 | $ResGroupNames = $ResGroupsArray | Foreach-Object {$_.NetworkResourceGroupName} | Select -Unique 99 | 100 | #Connect to Azure 101 | Write-output "Connecting to Azure" 102 | 103 | # Get the connection "AzureRunAsConnection " 104 | $Conn = Get-AutomationConnection -Name $connectionName 105 | $Cred = Get-AutomationPSCredential -Name 'ASRServicePrincipal' 106 | 107 | $AzureLoginResults = Login-AzureRmAccount -ServicePrincipal -Credential $Cred -TenantId $Conn.TenantId -ErrorAction SilentlyContinue -ErrorVariable LoginError 108 | 109 | #$AzureADLoginResults 110 | #$LoginADError 111 | if ($LoginError.Count -gt 0) 112 | { 113 | $ErrorDetails = $LoginError.Exception.Message; 114 | Write-Output "Login failed with Error: $ErrorDetails" 115 | $LoginStatus = "Failed" 116 | 117 | $RetunrObjItm = new-object PSObject 118 | $RetunrObjItm | add-member NoteProperty "Virtual Machine Operator Status" -value $LoginStatus 119 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 120 | 121 | } 122 | else 123 | { 124 | Write-Output "Setting Subscription" 125 | $subs = Get-AzureRmSubscription 126 | 127 | Write-Output "Connecting to Azure AD" 128 | 129 | $AzureADLoginResults = Connect-AzureAD -ApplicationId $Conn.ApplicationId -TenantId $Conn.TenantId -CertificateThumbprint $Conn.CertificateThumbprint -ErrorAction SilentlyContinue -ErrorVariable LoginADError 130 | 131 | #Check for Login Errors 132 | if ($LoginADError.Count -gt 0) 133 | { 134 | $ErrorDetails = $LoginADError.Exception.Message; 135 | Write-Output "Login AD failed with Error: $ErrorDetails" 136 | $LoginStatus = "Failed" 137 | 138 | $RetunrObjItm = new-object PSObject 139 | $RetunrObjItm | add-member NoteProperty "Virtual Machine Operator Status" -value $LoginStatus 140 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 141 | 142 | } 143 | else 144 | { 145 | Write-Output "Execute process per each Azure Subscription" 146 | 147 | foreach ($sub in $subs) 148 | { 149 | $SubscriptionID=$sub.Id 150 | $SubsName = $sub.Name 151 | Write-Output "Connecting to Azure Subscription $SubsName" 152 | Select-AzureRmSubscription -SubscriptionId $SubscriptionID -TenantId $Conn.TenantId 153 | 154 | Write-output "Getting VM Collection from Azure" 155 | $VMs = Get-AzureRmVM -Status -WarningAction SilentlyContinue 156 | 157 | Write-output "Extracting Regions from VMs in Azure" 158 | 159 | $VMLocations = $VMs | Foreach-Object {$_.Location} | Select -Unique 160 | 161 | Write-output "Extracting Resource Groups from VMs in Azure" 162 | 163 | $VMResourceGroups = $VMs | Foreach-Object {$_.ResourceGroupName} | Select -Unique 164 | 165 | Write-output "Filtering Resource Groups from not existant in DB" 166 | 167 | $FilteredVMResourceGroups = $VMResourceGroups | Where-Object {$_ -notin $ResGroupNames} 168 | 169 | $SqlQuery3 = "" 170 | 171 | Write-output "Adding new Resource Groups from Azure to SQL Database" 172 | 173 | foreach ($ResGroupItm in $FilteredVMResourceGroups) 174 | { 175 | $ResourceGroupObj = Get-AzureRmResourceGroup -Name $ResGroupItm 176 | 177 | $ResourceGroupRegion = $ResourceGroupObj.Location 178 | 179 | switch ($ResourceGroupRegion) { 180 | "eastus2" {$VMRegionID = 1; break} 181 | "eastus" {$VMRegionID = 2; break} 182 | } 183 | 184 | $ResourceGroupId = $ResourceGroupObj.ResourceId 185 | $ResourceGroupSubscription = $ResourceGroupObj.ResourceId.Split("/")[2] 186 | $ResourceGroupName = $ResourceGroupObj.ResourceGroupName 187 | 188 | $CurrSqlQuery = "Insert into [dbo].[NetworkResourceGroup] Values ('$ResourceGroupId','$ResourceGroupSubscription','$ResourceGroupName',$VMRegionID,'1'); " 189 | #$CurrSqlQuery 190 | $SqlQuery3 += $CurrSqlQuery 191 | } 192 | 193 | if ($SqlQuery3 -ne "") 194 | { 195 | Write-output "New Resource Groups ready to be added to SQL Database" 196 | 197 | $SqlCmd.CommandText = $SqlQuery3 198 | $SqlAdapter.InsertCommand = $SqlCmd 199 | $SqlCmd.ExecuteNonQuery() 200 | 201 | Write-output "New Resource Groups added to SQL Database" 202 | } 203 | 204 | Write-output "Getting new collection of Resource Groups from SQL Database" 205 | 206 | $Dataset.Reset() 207 | $SqlQuery4 = "Select [NetworkResourceGroupID], [NetworkResourceGroupName], [RegionID] from [dbo].[NetworkResourceGroup]" 208 | $SqlCmd.CommandText = $SqlQuery4 209 | $SqlAdapter.SelectCommand = $SqlCmd 210 | $SqlAdapter.Fill($Dataset) 211 | 212 | # Output the count 213 | $ResGroupsTable = $Dataset.Tables[0] 214 | 215 | #Load Data in Array 216 | $ResGroupsArray = @() 217 | $ResGroupsArray = @($ResGroupsTable) 218 | 219 | Write-output "Filter collection of VMs that are not in DB to add them to SQL Database" 220 | 221 | ##$FilteredNewVMs = $VMs | Where-Object {$_.Name -notin $VMNames -and $_.PowerState -eq "VM running"} | Select-Object -First 5 222 | #$FilteredNewVMs = $VMs | Where-Object {$_.Name -notin $VMNames} | Select-Object -First $RecordsPerBatch 223 | #$FilteredNewVMs = $VMs | Select-Object -First $RecordsPerBatch 224 | $FilteredNewVMs = $VMs 225 | 226 | Write-output "New VM Collection to be added to SQL Database" 227 | #$FilteredNewVMs 228 | 229 | #GET VMS COUNT 230 | $VMNewCount = $FilteredNewVMs.Count 231 | 232 | Write-output "VMs to be added to Temp Table are $VMNewCount" 233 | 234 | $CurrYear = (Get-Date).Year.ToString() 235 | 236 | $BulkSQLCommand = "" 237 | 238 | Write-output "Adding to SQL Command to Bulk execution" 239 | Select-AzureRmSubscription -SubscriptionId $SubscriptionID -TenantId $Conn.TenantId 240 | 241 | for ($itmNewVM = 0; $itmNewVM -lt $VMNewCount; $itmNewVM++) 242 | { 243 | $CurrentVMCount += 1 244 | $VMRequestNumber = "AZUREQ" + $CurrYear + "{0:00000}" -f ($CurrentVMCount) 245 | 246 | $NewVM = $FilteredNewVMs[$itmNewVM] 247 | $VMName = $NewVM.Name 248 | $VMLocation = $NewVM.Location 249 | 250 | $VMResourceGroup = $NewVM.ResourceGroupName 251 | $VMResourceGroupDB = $ResGroupsArray | Where-Object {$_.NetworkResourceGroupName -eq $VMResourceGroup} 252 | $VMResourceGroupID = $VMResourceGroupDB.NetworkResourceGroupID 253 | $VMRegionID = $VMResourceGroupDB.RegionID 254 | 255 | $VMState = $NewVM.PowerState 256 | 257 | switch ($VMState) 258 | { 259 | "VM deallocated" {$VMStateID = 9; break} 260 | "VM deallocating" {$VMStateID = 9; break} 261 | "VM stopped" {$VMStateID = 8; break} 262 | "VM stopping" {$VMStateID = 8; break} 263 | "VM starting" {$VMStateID = 7; break} 264 | "VM running" {$VMStateID = 7; break} 265 | } 266 | $Tags = (Get-AzureRmResource -ResourceName $VMName -ResourceGroupName $VMResourceGroup).Tags 267 | $VMScope = (Get-AzureRmResource -ResourceGroupName $VMResourceGroup -ResourceName $VMName).ResourceId 268 | $AzureRoleObjColl = Get-AzureRmRoleAssignment -Scope $VMScope -RoleDefinitionName $Role -ErrorAction SilentlyContinue -ErrorVariable AzureRoleDefError 269 | 270 | $VMTagApplicationType = $Tags.ApplicationType 271 | $VMTagApplicationOwner = $Tags.ApplicationOwner 272 | $VMTagCostCenter = $Tags.CostCenter 273 | $VMTagApplicationCategory = $Tags.ApplicationCategory 274 | $VMTagDepartment = $Tags.Department 275 | 276 | if ($VMTagApplicationType -eq "" -or $VMTagApplicationType -eq $null -or $VMTagApplicationType -eq "None") 277 | { 278 | $VMTagApplicationType = "N/A" 279 | } 280 | 281 | if ($VMTagApplicationOwner -eq "" -or $VMTagApplicationOwner -eq $null -or $VMTagApplicationOwner -eq "None") 282 | { 283 | $VMTagApplicationOwner = "N/A" 284 | } 285 | 286 | if ($VMTagCostCenter -eq "" -or $VMTagCostCenter -eq $null -or $VMTagCostCenter -eq "None") 287 | { 288 | $VMTagCostCenter = "N/A" 289 | } 290 | 291 | if ($VMTagApplicationCategory -eq "" -or $VMTagApplicationCategory -eq $null -or $VMTagApplicationCategory -eq "None") 292 | { 293 | $VMTagApplicationCategory = "N/A" 294 | } 295 | 296 | if ($VMTagDepartment -eq "" -or $VMTagDepartment -eq $null -or $VMTagDepartment -eq "None") 297 | { 298 | $VMTagDepartment = "N/A" 299 | } 300 | 301 | if ($AzureRoleObjColl -eq $null) 302 | { 303 | Write-output "Adding $VMRequestNumber Unassigned VM $VMName to to SQL Command" 304 | 305 | $VMMachineComment = "Virtual Machine Unassigned" 306 | 307 | $CurrentSQLCommand = " insert into [dbo].[AzureTempVMs] values ('$VMRequestNumber','$VMName',0,23,0,23,'0',1,'$DefaultRoleUserDisplayName','password','$DefaultRoleUserSignInName',1,$VMStateID,1,1,4,1,NULL,'N/A','$VMMachineComment',1,$VMRegionID,$VMResourceGroupID,1,1,'$SubscriptionID'); " 308 | #$CurrentSQLCommand 309 | 310 | $BulkSQLCommand += $CurrentSQLCommand 311 | } 312 | else 313 | { 314 | foreach ($AzureRoleObj in $AzureRoleObjColl) 315 | { 316 | #Iterate the Group and its members in Virtual Machine Operator Role 317 | if($AzureRoleObj.ObjectType -eq 'Group') 318 | { 319 | $AzureObjectId = $AzureRoleObj.ObjectId 320 | #$AzureObjectId 321 | $members= Get-AzureADGroupMember -ObjectId $AzureObjectId -ErrorAction SilentlyContinue -ErrorVariable AzureADGroupMemberError 322 | 323 | if ($AzureADGroupMemberError.Count -gt 0) 324 | { 325 | $ErrorDetails = $AzureADGroupMemberError.Exception.Message; 326 | Write-Output "Get-AzureADGroupMember failed with Error: $ErrorDetails" 327 | } 328 | else 329 | { 330 | foreach ($member in $members) 331 | { 332 | $CurrentVMCount +=1 333 | $VMRequestNumber = "AZUREQ" + $CurrYear + "{0:00000}" -f ($CurrentVMCount) 334 | 335 | $RoleUserDisplayName = $member.DisplayName 336 | $RoleUserSignInName = $member.UserPrincipalName 337 | 338 | Write-output "Adding $VMRequestNumber assigned to $RoleUserDisplayName VM $VMName to to SQL Command" 339 | 340 | $VMMachineComment = "Virtual Machine Assigned to $RoleUserDisplayName" 341 | 342 | $CurrentSQLCommand = " insert into [dbo].[AzureTempVMs] values ('$VMRequestNumber','$VMName',0,23,0,23,'0',1,'$RoleUserDisplayName','password','$RoleUserSignInName',1,$VMStateID,1,1,4,1,NULL,'N/A','$VMMachineComment',1,$VMRegionID,$VMResourceGroupID,1,1,'$SubscriptionID'); " 343 | # $CurrentSQLCommand 344 | 345 | $BulkSQLCommand += $CurrentSQLCommand 346 | } 347 | } 348 | } 349 | #Iterate the User in Virtual Machine Operator Role 350 | else 351 | { 352 | $CurrentVMCount += 1 353 | $VMRequestNumber = "AZUREQ" + $CurrYear + "{0:00000}" -f ($CurrentVMCount) 354 | 355 | $RoleUserDisplayName = $AzureRoleObj.DisplayName 356 | $RoleUserSignInName = $AzureRoleObj.SignInName 357 | 358 | 359 | Write-output "Adding $VMRequestNumber assigned to $RoleUserDisplayName VM $VMName to to SQL Command" 360 | 361 | $VMMachineComment = "Virtual Machine Assigned to $RoleUserDisplayName" 362 | 363 | $CurrentSQLCommand = " insert into [dbo].[AzureTempVMs] values ('$VMRequestNumber','$VMName',0,23,0,23,'0',1,'$RoleUserDisplayName','password','$RoleUserSignInName',1,$VMStateID,1,1,4,1,NULL,'N/A','$VMMachineComment',1,$VMRegionID,$VMResourceGroupID,1,1,'$SubscriptionID'); " 364 | #$CurrentSQLCommand 365 | 366 | $BulkSQLCommand += $CurrentSQLCommand 367 | } 368 | 369 | } 370 | 371 | } 372 | 373 | #END OF FOR EACH VM 374 | } 375 | 376 | if ($BulkSQLCommand -ne "") 377 | { 378 | Write-output "Prepared to Execute Bulk SQL Command" 379 | $BulkSqlCmd = New-Object System.Data.SqlClient.SqlCommand 380 | $BulkSqlAdapter = New-Object system.Data.SqlClient.SqlDataAdapter 381 | $BulkSqlCmd.CommandTimeout = 120 382 | $BulkSqlCmd.Connection = $SQLConn 383 | $BulkSqlCmd.CommandType = [System.Data.CommandType]::Text 384 | $BulkSqlCmd.CommandText = $BulkSQLCommand 385 | $BulkSqlAdapter.InsertCommand = $BulkSqlCmd 386 | $BulkSqlCmd.ExecuteNonQuery() 387 | Write-output "Executed Bulk SQL Command" 388 | $BulkSQLCommand="" 389 | $BulkSqlCmd=$null 390 | $BulkSqlAdapter=$null 391 | #Executing Final Stored Procedure to Update VM Table 392 | 393 | Write-output "Executing Final Stored Procedure to Update VM Table" 394 | 395 | $SPSqlCmd = New-Object System.Data.SqlClient.SqlCommand 396 | $SPSqlAdapter = New-Object system.Data.SqlClient.SqlDataAdapter 397 | $SPSqlCmd.CommandTimeout = 120 398 | $SPSqlCmd.Connection = $SQLConn 399 | $SPSqlCmd.CommandText = "UpDateVMTable" 400 | $SPSqlCmd.CommandType = [System.Data.CommandType]::StoredProcedure 401 | $SPSqlCmd.Parameters.Add("@SubscriptionID", "$SubscriptionID") 402 | $SPSqlAdapter.UpdateCommand = $SPSqlCmd 403 | $SPSqlCmd.ExecuteNonQuery() 404 | $SPSqlCmd=$null 405 | $SPSqlAdapter=$null 406 | Write-output "Executed UpdateVMTable Stored Procedure" 407 | $Dataset.Reset() 408 | $ResGroupsTable.Reset() 409 | } 410 | 411 | #END OF FOR EACH SUBS 412 | } 413 | 414 | #END OF ELSE 415 | } 416 | 417 | 418 | } 419 | 420 | # Close the SQL connection 421 | $SQLConn.Close() 422 | 423 | $FinalExecutionDatetime = (Get-Date) 424 | 425 | $InitialExecutionDatetimeDate = $InitialExecutionDatetime.Date 426 | $FinalExecutionDatetimeDate = $FinalExecutionDatetime.Date 427 | 428 | Write-Output "Script Started at $InitialExecutionDatetimeDate" 429 | Write-Output "Script Finished at $FinalExecutionDatetimeDate" 430 | 431 | [int32] $TotalExecutionTimeInSeconds = (New-TimeSpan -Start $InitialExecutionDatetime -End $FinalExecutionDatetime).TotalSeconds 432 | [int32] $TotalExecutionTimeInMinutes = ($TotalExecutionTimeInSeconds / 60) 433 | 434 | 435 | Write-Output "Total Script execution time in Seconds $TotalExecutionTimeInSeconds" 436 | Write-Output "Total Script execution time in Minutes $TotalExecutionTimeInMinutes" 437 | -------------------------------------------------------------------------------- /Scripts/Get-SubnetsReport/Get-SubnetsReport01.ps1: -------------------------------------------------------------------------------- 1 | Login-AzureRmAccount 2 | 3 | Get-AzureRmSubscription 4 | 5 | Select-AzureRmSubscription -Subscription subprod01 6 | 7 | #$AzureVirtualNetwork= Get-AzureRmVirtualNetwork | Select-Object -ExpandProperty ResourceGrounName, Name, Location, AddressSpace,Subnets 8 | $OutFileLocation='C:\Projects\test' 9 | try 10 | { 11 | $subscriptions=Get-AzureRmSubscription 12 | $objects = @() 13 | foreach ($subscription in $subscriptions) 14 | { 15 | Select-AzureRmSubscription -Subscription $subscription.Id 16 | $AzureVirtualNetwork=Get-AzureRmVirtualNetwork | Select-Object -Property Name ,@{ Name='AddressSpace';Express={$_.AddressSpace.AddressPrefixes} },@{ Name='virtualnetworkIP';Express={($_.AddressSpace.AddressPrefixes).Split('/')[0] } } ,@{ Name='SubnetName';Express={($_.Subnets.Name) } },@{ Name='SubnetAddress';Express={($_.Subnets.AddressPrefix) } } 17 | 18 | foreach ($vn in $AzureVirtualNetwork) 19 | { 20 | 21 | for ($i = 0; $i -lt $vn.SubnetAddress.Count; $i++) 22 | { 23 | $subnetName=$vn.SubnetName[$i] 24 | $virtualnetworkName=$vn.Name 25 | Write-Host "Getting Subnets for VirtualNetwork and SubnetName are $virtualnetworkName $subnetName" 26 | 27 | 28 | if ($vn.SubnetAddress.Count -eq 1) 29 | { 30 | $subnetName=$vn.SubnetName 31 | $subnetLength=$vn.SubnetAddress.Split('/')[1] 32 | $subnetAddressSpace=$vn.SubnetAddress 33 | $subnetAddress=$vn.SubnetAddress.Split('/')[0].Split('.') 34 | } 35 | else 36 | { 37 | $subnetLength=$vn.SubnetAddress[$i].Split('/')[1] 38 | $subnetAddress=$vn.SubnetAddress[$i].Split('/')[0].Split('.') 39 | $subnetAddressSpace=$vn.SubnetAddress[$i] 40 | } 41 | 42 | switch ($subnetLength) { 43 | "24" {$subnetRange=254; break} 44 | "25" {$subnetRange=126; break} 45 | "26" {$subnetRange=62; break} 46 | "27" {$subnetRange=30; break} 47 | "28" {$subnetRange=14; break} 48 | default {$subnetRange=0; break} 49 | } 50 | for ($j = 1; $j -le $subnetRange; $j++) 51 | { 52 | $subnetIpAddresses= $subnetAddress[0] + "." + $subnetAddress[1] + "." + $subnetAddress[2] + "." + ($j +$subnetAddress[3]) 53 | $objects += New-Object -Type PSObject -Prop @{'VirtualNetwork'=$vn.Name;'AddressSpace'=$vn.AddressSpace;'SubnetName'=$subnetName;'SubnetAddressSpace'=$subnetAddressSpace;'IPAddresses'=$subnetIpAddresses} 54 | } 55 | 56 | Write-Host "Test" 57 | 58 | } 59 | 60 | } 61 | } 62 | $objects|export-csv -NoTypeInformation ($OutFileLocation + '\' + (get-date -format yyyy-MM-dd) + '_subnetAddresses.csv') 63 | } 64 | 65 | catch { 66 | throw $Error[0].Exception.Message 67 | } 68 | -------------------------------------------------------------------------------- /Scripts/Get-SubnetsReport/Subnet Reports script details.md: -------------------------------------------------------------------------------- 1 | The Get-SubnetsReport.ps1 script helps you generate a report of all the subnets for all the vNets in your environment. This helps you to compare this data or use this data for any kind of the networking related reports. 2 | The script includes the commands to log into the portal as well and select all the subscriptions. It then iterates over various virtual networks and subnets. 3 | -------------------------------------------------------------------------------- /Scripts/Get-VMRunning/VMRunning24hrs.ps1: -------------------------------------------------------------------------------- 1 | $InitialExecutionDatetime = (Get-Date) 2 | $CurrentDateTime=$InitialExecutionDatetime.ToUniversalTime() 3 | $connectionName = "AzureRunAsConnection" 4 | $Conn = Get-AutomationConnection -Name $connectionName 5 | $Cred = Get-AutomationPSCredential -Name 'ASRServicePrincipal' 6 | [int]$NoOfDays=1 7 | #$AutomationAccountName = Get-AutomationVariable -Name 'AzureAutomationAccountName' 8 | #$ResourceGroupName = Get-AutomationVariable -Name 'AzureAutomationAccountRG' 9 | #$currentSubscriptionId="" 10 | Write-output "Login to Azure" 11 | $AzureLoginResults =Login-AzureRmAccount 12 | #$AzureLoginResults = Login-AzureRmAccount -ServicePrincipal -Credential $Cred -TenantId $Conn.TenantId -ErrorAction SilentlyContinue -ErrorVariable LoginError 13 | $RetunrObjItm = new-object PSObject 14 | [int]$counter=0 15 | $result="" 16 | <#$AzureLoginResults = Login-AzureRmAccount ` 17 | -ServicePrincipal ` 18 | -TenantId $Conn.TenantId ` 19 | -ApplicationId $Conn.ApplicationId ` 20 | -CertificateThumbprint $Conn.CertificateThumbprint -ErrorAction SilentlyContinue -ErrorVariable LoginError `#> 21 | 22 | if ($LoginError.Count -gt 0) 23 | { 24 | $ErrorDetails = $LoginError.Exception.Message; 25 | Write-Output "Login failed with Error: $ErrorDetails" 26 | $LoginStatus = "Failed" 27 | 28 | 29 | $RetunrObjItm | add-member NoteProperty "Virtual Machine Operator Status" -value $LoginStatus 30 | $RetunrObjItm | add-member NoteProperty "ErrorDetails" -value $ErrorDetails 31 | 32 | } 33 | else 34 | { 35 | Write-Output "Successfully Login to Azure" 36 | Write-Output "Setting Up Subscription" 37 | $subs = Get-AzureRmSubscription 38 | $jobs = @() 39 | foreach ($sub in $subs) 40 | { 41 | #if ($sub.Id -eq "adf124da-c139-44c5-b226-3a812fbe6cf0" -or $sub.Id -eq "f1e34301-c396-4b15-9f25-cab99b61ce7a" -or $sub.Id -eq "dc212303-893e-404d-a787-3a960b14e8bf") 42 | #{ 43 | $SubscriptionID = $sub.Id 44 | $SelectSub = Select-AzureRmSubscription -SubscriptionId $SubscriptionID -TenantId $sub.TenantId 45 | Write-Output "Getting VM Collection from Azure for subscription $($sub.Name)" 46 | $VMs = Get-AzureRmVM -Status| Where-Object { $_.PowerState -in ('VM Running','VM allocating','VM Starting') } -WarningAction SilentlyContinue 47 | $VMs | Format-Table 48 | foreach($VM in $VMs) 49 | { 50 | $VMTime=(Get-AzureRmVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Status).Statuses.Time 51 | $starTime=[System.DateTime]::Parse($VMTime) 52 | [int]$TotalExecutionTimeInHours = (New-TimeSpan -Start $starTime -End $CurrentDateTime).TotalDays 53 | if($TotalExecutionTimeInHours -gt $NoOfDays) 54 | { 55 | Write-Output "VM Name $($VM.Name)" 56 | $counter++ 57 | $RetunrObjItm | add-member NoteProperty "$($counter)) VMName" -value $VM.Name 58 | $RetunrObjItm | add-member NoteProperty "$($counter)) ResourceGroupName" -value $VM.ResourceGroupName 59 | $RetunrObjItm | add-member NoteProperty "$($counter)) NoOfDays$($VM.Name)Running" -value $TotalExecutionTimeInHours 60 | $RetunrObjItm | add-member NoteProperty "$($counter)) $($VM.Name)SubscriptonName" -value $sub.Name 61 | $RetunrObjItm | add-member NoteProperty "$($counter)) $($VM.Name)SubscriptonID" -value $sub.Id 62 | $result+=$VM 63 | } 64 | } 65 | 66 | #} 67 | } 68 | } 69 | $RetunrObjItm 70 | 71 | Write-Output "Sending an email" 72 | $Username ="gurpreetsambhi" # Your user name - found in sendgrid portal 73 | $Password = ConvertTo-SecureString "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" -AsPlainText -Force # SendGrid Password 74 | $credential = New-Object System.Management.Automation.PSCredential $Username, $Password 75 | $SMTPServer = "smtp.sendgrid.net" 76 | $EmailFrom = "gurpreet_sambhi@outlook.com" # Can be anything - aaa@xyz.com 77 | $EmailTo = "gurpreet.sambhi@infrontconsulting.com" # Valid recepient email address 78 | $Subject = "Azure VM Running Report" 79 | $Body = "Summary as of: " + (Get-Date -Format G) + " UTC"+ "`n`n" + $result 80 | 81 | Send-MailMessage -smtpServer $SMTPServer -Credential $credential -Usessl -Port 587 -from $EmailFrom -to $EmailTo -subject $Subject -Body $Body 82 | #-Attachments $file_path_for_nsg, $file_path_for_running_VM, $file_path_for_deallocated_VM, $file_path_for_stopped_VM, $file_path_for_vm_with_no_backup 83 | 84 | 85 | $FinalExecutionDatetime = (Get-Date) 86 | [int32] $TotalExecutionTimeInMinutes = (New-TimeSpan -Start $InitialExecutionDatetime -End $FinalExecutionDatetime).TotalMinutes 87 | Write-Output "Total Script execution time in Minutes $TotalExecutionTimeInMinutes" -------------------------------------------------------------------------------- /Scripts/Install-SAPMonitoringExtensionInLoop/Install-SAPMonitoringExtensionInLoop.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | File: Install-MonitoringExtensionInLoop.ps1 5 | 6 | Purpose: To Install Monitoring Extension In Loop 7 | 8 | Version: 1.0.0.0 9 | 10 | Author: Aman Sharma 11 | ============================================================================================== 12 | .SYNOPSIS 13 | Installs monitoring extension in loop on Linux VMs 14 | 15 | .DESCRIPTION 16 | This script is used to Installs monitoring extension in loop on Linux VMs 17 | 18 | .EXAMPLE 19 | C:\PS> .\Install-MonitoringExtensionInLoop.ps1 20 | 21 | Description 22 | ----------- 23 | This command executes the script with default parameters. 24 | 25 | .INPUTS 26 | None. 27 | 28 | .OUTPUTS 29 | None. 30 | 31 | .LINK 32 | https://docs.microsoft.com/en-us/azure/virtual-machines/workloads/sap/deployment-guide#2ad55a0d-9937-4943-9dd2-69bc2b5d3de0 33 | #> 34 | 35 | #Inputs 36 | $subscriptionName = "you-subscription-name" 37 | 38 | #Adding Azure Account and Subscription 39 | $env = Get-AzEnvironment -Name "AzureCloud" 40 | Connect-AzAccount -Environment $env 41 | Set-AzContext -SubscriptionName $subscriptionName 42 | 43 | #Selecting all RGs that begins with the text. Notice the wildcard in the name 44 | #TODO: Update this to a specific resource group or a similar query with wildcards 45 | $allSapRGs = Get-AzResourceGroup -Name "RG-IT-*" 46 | 47 | foreach($currentRG in $allSapRGs) 48 | { 49 | #Fetch all resources in the RG 50 | $currentRGName = $currentRG.ResourceGroupName 51 | $VMs = Get-AzVM -ResourceGroupName $currentRGName 52 | 53 | #Iterating on the VMs 54 | foreach ($vm in $VMs) 55 | { 56 | $VMName = $vm.name 57 | $osType = $vm.StorageProfile.OsDisk.OsType 58 | Write-Host "Working on VM: $VMName" 59 | 60 | if ($osType -eq "Linux") { 61 | Write-Host "VM $VMName is a Linux VM. Proceeding with the installation." 62 | try { 63 | Set-AzVMAEMExtension -ResourceGroupName $currentRGName -VMName $VMName -InstallNewExtension 64 | 65 | Write-Host -ForegroundColor Green "Installed the extension on the VM $VMName" 66 | } 67 | catch { 68 | Write-Host -ForegroundColor Red "Error while installing extension." 69 | $Error[0] 70 | Write-Host -ForegroundColor Red "Error occured at:" 71 | $Error[0].InvocationInfo.PositionMessage 72 | } 73 | } 74 | else { 75 | Write-Host "VM $VMName is not a Linux VM" 76 | } 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Scripts/Move-AzVMToAvailabilityZone/Move-AzVMToAvailabilityZone.ps1: -------------------------------------------------------------------------------- 1 | #Input Parameters 2 | $subscriptionName = "Your-Subscription-Name" # subscription name where the VM exists 3 | #This path is only used to export the VM's JSON file in case of any script failures. 4 | #This should be any folder on your machine that should exist already 5 | $PathForVMExport = "D:\DATA\Scripts\Move-AzVMToAvailabilityZone" 6 | $resourceGroup = "Your-Resource-Group-Name" #Resouce group of the VM 7 | $vmName = "Your-VM-Name" #VM Name 8 | $location = "eastus2" #VM Location 9 | $zone = "1" #Valid Values are 1, 2 or 3 10 | 11 | function Export-VMConfig { 12 | [CmdletBinding()] 13 | param 14 | ( 15 | [Parameter(Mandatory=$True, 16 | HelpMessage='name of the Virtual Machine')] 17 | [Alias('vm')] 18 | [string]$virtualMachineName, 19 | 20 | [Parameter(Mandatory=$True, 21 | HelpMessage='name of the Resource Group of the Virtual Machine')] 22 | [Alias('rg')] 23 | [string]$ResourceGroupName, 24 | 25 | [Parameter(Mandatory=$True, 26 | HelpMessage='directory path for export file')] 27 | [Alias('path')] 28 | [string]$PathForVMExport 29 | ) 30 | try 31 | { 32 | Write-Host "Exporting Information for VM $virtualMachineName." 33 | $currentVm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -ErrorAction Stop 34 | 35 | $timeStamp = (Get-Date).ToString("MM-dd-yyyy-HH-mm-ss") 36 | $fileNameWithPath = "" 37 | if($PathForVMExport.EndsWith('\')) 38 | { 39 | $fileNameWithPath = $PathForVMExport + $virtualMachineName + "-" + $timeStamp + '.json' 40 | } 41 | else { 42 | $fileNameWithPath = $PathForVMExport + "\" + $virtualMachineName + "-" + $timeStamp + '.json' 43 | } 44 | 45 | Write-Host "Outputing VM configurations for VM $virtualMachineName at time $timeStamp ." 46 | $currentVm | ConvertTo-Json -Depth 100 | Out-File -FilePath $fileNameWithPath 47 | 48 | Write-Host -ForegroundColor Green "Successfully exported the information for the VM $virtualMachineName." 49 | } 50 | catch [system.exception] 51 | { 52 | Write-Host -ForegroundColor Red "Failed to export the information for VM $virtualMachineName. " 53 | Write-Host -ForegroundColor Red "Error in exporting VM Config for $virtualMachineName : $($_.Exception.Message) " 54 | Write-Host -ForegroundColor Red "Error Details are: " 55 | Write-Host -ForegroundColor Red $Error[0].ToString() 56 | } 57 | } 58 | 59 | try 60 | { 61 | #Logging in 62 | $env = Get-AzEnvironment -Name "AzureCloud" 63 | Connect-AzAccount -Environment $env 64 | Set-AzContext -SubscriptionName $subscriptionName 65 | 66 | #Exporting VM Config 67 | Export-VMConfig -virtualMachineName $vmName -ResourceGroupName $resourceGroup -PathForVMExport $PathForVMExport 68 | 69 | # Get the details of the VM to be moved to the Availability Set 70 | $originalVM = Get-AzVM -ResourceGroupName $resourceGroup -Name $vmName 71 | 72 | # Stop the VM to take a snapshot 73 | Stop-AzVM -ResourceGroupName $resourceGroup -Name $vmName -Force 74 | 75 | # Create a SnapShot of the OS disk and then, create an Azure Disk with Zone information 76 | $snapshotOSConfig = New-AzSnapshotConfig -SourceUri $originalVM.StorageProfile.OsDisk.ManagedDisk.Id -Location $location -CreateOption copy -SkuName Standard_ZRS 77 | $OSSnapshot = New-AzSnapshot -Snapshot $snapshotOSConfig -SnapshotName ($originalVM.StorageProfile.OsDisk.Name + "-snapshot") -ResourceGroupName $resourceGroup 78 | $diskSkuOS = (Get-AzDisk -DiskName $originalVM.StorageProfile.OsDisk.Name -ResourceGroupName $originalVM.ResourceGroupName).Sku.Name 79 | 80 | $diskConfig = New-AzDiskConfig -Location $OSSnapshot.Location -SourceResourceId $OSSnapshot.Id -CreateOption Copy -SkuName $diskSkuOS -Zone $zone 81 | $OSdisk = New-AzDisk -Disk $diskConfig -ResourceGroupName $resourceGroup -DiskName ($originalVM.StorageProfile.OsDisk.Name + "zone") 82 | 83 | 84 | # Create a Snapshot from the Data Disks and the Azure Disks with Zone information 85 | foreach ($disk in $originalVM.StorageProfile.DataDisks) { 86 | 87 | $snapshotDataConfig = New-AzSnapshotConfig -SourceUri $disk.ManagedDisk.Id -Location $location -CreateOption copy -SkuName Standard_ZRS 88 | $DataSnapshot = New-AzSnapshot -Snapshot $snapshotDataConfig -SnapshotName ($disk.Name + '-snapshot') -ResourceGroupName $resourceGroup 89 | 90 | $diskSkuData = (Get-AzDisk -DiskName $disk.Name -ResourceGroupName $originalVM.ResourceGroupName).Sku.Name 91 | $datadiskConfig = New-AzDiskConfig -Location $DataSnapshot.Location -SourceResourceId $DataSnapshot.Id -CreateOption Copy -SkuName $diskSkuData -Zone $zone 92 | $datadisk = New-AzDisk -Disk $datadiskConfig -ResourceGroupName $resourceGroup -DiskName ($disk.Name + "-zone") 93 | } 94 | 95 | # Remove the original VM 96 | Remove-AzVM -ResourceGroupName $resourceGroup -Name $vmName -Force 97 | 98 | # Create the basic configuration for the replacement VM 99 | 100 | $newVM = New-AzVMConfig -VMName $originalVM.Name -VMSize $originalVM.HardwareProfile.VmSize -Zone $zone 101 | 102 | #Retaining the Tags 103 | $newVM.Tags = $originalVM.Tags 104 | 105 | #Retaining the Boot diagnostics storage account 106 | $newVM.DiagnosticsProfile = $originalVM.DiagnosticsProfile 107 | 108 | # Add the pre-existed OS disk 109 | if($OSdisk.OsType -eq "Linux") 110 | { 111 | Set-AzVMOSDisk -VM $newVM -CreateOption Attach -ManagedDiskId $OSdisk.Id -Name $OSdisk.Name -Linux 112 | } 113 | else { 114 | Set-AzVMOSDisk -VM $newVM -CreateOption Attach -ManagedDiskId $OSdisk.Id -Name $OSdisk.Name -Windows 115 | } 116 | # Add the pre-existed data disks 117 | foreach ($disk in $originalVM.StorageProfile.DataDisks) { 118 | $datadisk = Get-AzDisk -ResourceGroupName $resourceGroup -DiskName ($disk.Name + "-zone") 119 | Add-AzVMDataDisk -VM $newVM -Name $datadisk.Name -ManagedDiskId $datadisk.Id -Caching $disk.Caching -Lun $disk.Lun -DiskSizeInGB $disk.DiskSizeGB -CreateOption Attach 120 | } 121 | 122 | # Add NIC(s) and keep the same NIC as primary 123 | # If there is a Public IP from the Basic SKU remove it because it doesn't supports zones 124 | foreach ($nic in $originalVM.NetworkProfile.NetworkInterfaces) 125 | { 126 | $netInterface = Get-AzNetworkInterface -ResourceId $nic.Id 127 | $publicIPId = $netInterface.IpConfigurations[0].PublicIpAddress.Id 128 | $publicIP = Get-AzPublicIpAddress -Name $publicIPId.Substring($publicIPId.LastIndexOf("/")+1) 129 | if ($publicIP) 130 | { 131 | if ($publicIP.Sku.Name -eq 'Basic') 132 | { 133 | $netInterface.IpConfigurations[0].PublicIpAddress = $null 134 | Set-AzNetworkInterface -NetworkInterface $netInterface 135 | } 136 | } 137 | if ($nic.Primary -eq "True") 138 | { 139 | Add-AzVMNetworkInterface -VM $newVM -Id $nic.Id -Primary 140 | } 141 | else 142 | { 143 | Add-AzVMNetworkInterface -VM $newVM -Id $nic.Id 144 | } 145 | } 146 | 147 | # Recreate the VM 148 | New-AzVM -ResourceGroupName $resourceGroup -Location $originalVM.Location -VM $newVM -DisableBginfoExtension 149 | 150 | Write-Host -ForegroundColor Green "Successfully moved the VM to Availability Zone" 151 | Write-Host -ForegroundColor Red "MANUAL ACTION REQUIRED: Validate the new VM and then delete the older OS and Data disks and any related snapshots" 152 | 153 | } 154 | catch [system.exception] 155 | { 156 | Write-Verbose "Error : $($_.Exception.Message) " 157 | Write-Host "Error : $($_.Exception.Message) " 158 | Write-Verbose "Error Details are: " 159 | Write-Verbose $Error[0].ToString() 160 | } 161 | -------------------------------------------------------------------------------- /Scripts/Remove-Locks/Remove-Locks.ps1: -------------------------------------------------------------------------------- 1 | Add-AzureRmAccount 2 | 3 | $subs = Get-AzureRmSubscription 4 | 5 | #Checking if the subscriptions are found or not 6 | if(($subs -ne $null) -or ($subs.Count -gt 0)) 7 | { 8 | #Creating Output Object 9 | $results = @() 10 | 11 | #Iterating over various subscriptions 12 | foreach($sub in $subs) 13 | { 14 | $SubscriptionId = $sub.SubscriptionId 15 | Write-Output $SubscriptionName 16 | 17 | #Selecting the Azure Subscription 18 | Select-AzureRmSubscription -SubscriptionId $SubscriptionId 19 | 20 | #Getting all Azure Route Tables 21 | $routeTables = Get-AzureRmRouteTable 22 | 23 | #Iterating through Route Tables 24 | foreach($routeTable in $routeTables) 25 | { 26 | #Removing locks from the Route Tables 27 | Remove-AzureRmResourceLock -LockName DoNotDelete -ResourceGroupName $routeTable.ResourceGroupName -ResourceName $routeTable.Name -ResourceType $routeTable.Type -Force 28 | } 29 | 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /Scripts/Request-Rest.ps1: -------------------------------------------------------------------------------- 1 | #Reference: http://blogs.technet.com/b/scorch/archive/2011/05/25/getting-ready-for-orchestrator-2012-accessing-rest-web-services-using-powershell.aspx 2 | 3 | function Request-Rest{ 4 | [CmdletBinding()] 5 | PARAM ( 6 | [Parameter(Mandatory=$False)] 7 | [String]$Metadata, 8 | 9 | [Parameter(Mandatory=$true)] 10 | [String] $URL, 11 | 12 | [Parameter(Mandatory=$False)] 13 | [Switch]$listUpdate, 14 | 15 | [Parameter(Mandatory=$False)] 16 | [String]$RequestDigest, 17 | 18 | [Parameter(Mandatory=$false)] 19 | [System.Net.NetworkCredential] $credentials, 20 | 21 | [Parameter(Mandatory=$false)] 22 | [String] $UserAgent = "PowerShell API Client", 23 | 24 | [Parameter(Mandatory=$false)] 25 | [Switch] $JSON, 26 | 27 | [Parameter(Mandatory=$false)] 28 | [Switch] $Raw 29 | ) 30 | #Create a URI instance since the HttpWebRequest.Create Method will escape the URL by default. 31 | #$URL = Fix-Url $Url 32 | $URI = New-Object System.Uri($URL,$true) 33 | 34 | #Create a request object using the URI 35 | $request = [System.Net.HttpWebRequest]::Create($URI) 36 | 37 | #Build up a nice User Agent 38 | $request.UserAgent = $( 39 | "{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}), 40 | [Environment]::Version, 41 | [Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win") 42 | ) 43 | 44 | if ($credentials -eq $null) 45 | { 46 | $request.UseDefaultCredentials = $true 47 | } 48 | else 49 | { 50 | $request.Credentials = $credentials 51 | } 52 | 53 | $request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f") 54 | 55 | #Request Method 56 | $request.Method = "GET" 57 | 58 | #Headers 59 | if($listUpdate) 60 | { 61 | $request.Headers.Add("X-RequestDigest", $RequestDigest) 62 | $request.Headers.Add("If-Match", "*") 63 | $request.Headers.Add("X-HTTP-Method", "MERGE") 64 | 65 | $request.ContentType = "application/json;odata=verbose" 66 | $request.Accept = "application/json;odata=verbose" 67 | } 68 | 69 | #Request Body 70 | if($Metadata) { 71 | $Body = [byte[]][char[]]$Metadata 72 | $request.ContentLength = $Body.Length 73 | 74 | $stream = $request.GetRequestStream() 75 | $stream.Write($Body, 0, $Body.Length) 76 | } 77 | else { 78 | $request.ContentLength = 0 79 | } 80 | 81 | 82 | try 83 | { 84 | [System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse() 85 | } 86 | catch 87 | { 88 | Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)" 89 | } 90 | 91 | $reader = [IO.StreamReader] $response.GetResponseStream() 92 | 93 | if (($PSBoundParameters.ContainsKey('JSON')) -or ($PSBoundParameters.ContainsKey('Raw'))) 94 | { 95 | $output = $reader.ReadToEnd() 96 | } 97 | else 98 | { 99 | $output = $reader.ReadToEnd() 100 | } 101 | 102 | $reader.Close() 103 | 104 | if($output.StartsWith("" + $output + "") 111 | } 112 | 113 | Write-Output $outputXML 114 | 115 | $response.Close() 116 | } -------------------------------------------------------------------------------- /Scripts/Request-RestPost.ps1: -------------------------------------------------------------------------------- 1 | #Reference: http://blogs.technet.com/b/scorch/archive/2011/05/25/getting-ready-for-orchestrator-2012-accessing-rest-web-services-using-powershell.aspx 2 | 3 | function Request-Rest{ 4 | [CmdletBinding()] 5 | PARAM ( 6 | [Parameter(Mandatory=$False)] 7 | [String]$RequestBody, 8 | 9 | [Parameter(Mandatory=$true)] 10 | [String] $URL, 11 | 12 | [Parameter(Mandatory=$False)] 13 | [Switch]$listUpdate, 14 | 15 | [Parameter(Mandatory=$False)] 16 | [String]$RequestDigest, 17 | 18 | [Parameter(Mandatory=$false)] 19 | [System.Net.NetworkCredential] $credentials, 20 | 21 | [Parameter(Mandatory=$false)] 22 | [String] $UserAgent = "PowerShell API Client", 23 | 24 | [Parameter(Mandatory=$false)] 25 | [Switch] $JSON, 26 | 27 | [Parameter(Mandatory=$false)] 28 | [Switch] $Raw 29 | ) 30 | #Create a URI instance since the HttpWebRequest.Create Method will escape the URL by default. 31 | #$URL = Fix-Url $Url 32 | $URI = New-Object System.Uri($URL,$true) 33 | 34 | #Create a request object using the URI 35 | $request = [System.Net.HttpWebRequest]::Create($URI) 36 | 37 | #Build up a nice User Agent 38 | $request.UserAgent = $( 39 | "{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}), 40 | [Environment]::Version, 41 | [Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win") 42 | ) 43 | 44 | if ($credentials -eq $null) 45 | { 46 | $request.UseDefaultCredentials = $true 47 | } 48 | else 49 | { 50 | $request.Credentials = $credentials 51 | } 52 | 53 | $request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f") 54 | 55 | #Request Method 56 | $request.Method = "POST" 57 | 58 | #Headers 59 | if($listUpdate) 60 | { 61 | $request.Headers.Add("X-RequestDigest", $RequestDigest) 62 | $request.Headers.Add("If-Match", "*") 63 | $request.Headers.Add("X-HTTP-Method", "MERGE") 64 | 65 | $request.ContentType = "application/json;odata=verbose" 66 | $request.Accept = "application/json;odata=verbose" 67 | } 68 | 69 | #Request Body 70 | if($RequestBody) { 71 | $Body = [byte[]][char[]]$RequestBody 72 | $request.ContentLength = $Body.Length 73 | 74 | $stream = $request.GetRequestStream() 75 | $stream.Write($Body, 0, $Body.Length) 76 | } 77 | else { 78 | $request.ContentLength = 0 79 | } 80 | 81 | 82 | try 83 | { 84 | [System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse() 85 | } 86 | catch 87 | { 88 | Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)" 89 | } 90 | 91 | $reader = [IO.StreamReader] $response.GetResponseStream() 92 | 93 | if (($PSBoundParameters.ContainsKey('JSON')) -or ($PSBoundParameters.ContainsKey('Raw'))) 94 | { 95 | $output = $reader.ReadToEnd() 96 | } 97 | else 98 | { 99 | $output = $reader.ReadToEnd() 100 | } 101 | 102 | $reader.Close() 103 | 104 | if($output.StartsWith("" + $output + "") 111 | } 112 | 113 | Write-Output $outputXML 114 | 115 | $response.Close() 116 | } -------------------------------------------------------------------------------- /Scripts/StorageAccountBlobManagement.ps1: -------------------------------------------------------------------------------- 1 | #The below line will prompt for your credentials to login into Azure 2 | Add-AzAccount 3 | 4 | #Selecting the subscription if you have more than one subscriptions in your Azure account 5 | $context = Get-AzSubscription -SubscriptionId "1aa1aaa1-111-11a1-1a1e-bdf5f12e61db" 6 | Set-AzContext $context 7 | 8 | $StorageAccountName = "armtemplatesrepo" 9 | $ResourceGroupNameOfStorage = "ARMTemplatesRG" 10 | $ContainerName = "armtemplatesblob" 11 | 12 | #Set the Context in one of the 3 ways as per your security requirements 13 | #Ref: - https://azure.microsoft.com/en-us/documentation/articles/storage-powershell-guide-full/ 14 | $StorageAccountKey = Get-AzStorageAccountKey -AccountName $StorageAccountName -ResourceGroupName $ResourceGroupNameOfStorage 15 | $Ctx = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey[0].Value 16 | 17 | 18 | #Uploading File 19 | $BlobName = "Parameters.json" 20 | $localFile = "D:\Local\" + $BlobName 21 | 22 | #Note the Force switch will overwrite if the file already exists in the Azure container 23 | Set-AzStorageBlobContent -File $localFile -Container $ContainerName -Blob $BlobName -Context $Ctx -Force 24 | 25 | 26 | #Download File 27 | $BlobName = "Parameters.json" 28 | $localTargetDirectory = "D:\DownloadedFile" 29 | 30 | Get-AzStorageBlobContent -Blob $BlobName -Container $ContainerName -Destination $localTargetDirectory -Context $ctx 31 | -------------------------------------------------------------------------------- /Scripts/Tagging Reports/Get-AzureRmTagsReport - v3.0.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Microsoft Corporation. All rights reserved. 5 | 6 | File: Get-AzureRmTagsReport.ps1 7 | 8 | Purpose: To get the report for tags of all the resources in Azure 9 | 10 | Version: 3.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Azure Resources Tags Report Generation Script 16 | 17 | .DESCRIPTION 18 | This script is used to get the report for tags of all the resources in Azure. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Get-AzureRmTagsReport.ps1 22 | 23 | Description 24 | ----------- 25 | This command executes the script with default parameters. 26 | 27 | .INPUTS 28 | None. 29 | 30 | .OUTPUTS 31 | None. 32 | 33 | .LINK 34 | None. 35 | #> 36 | 37 | #Path variable to the CSV file 38 | #NOTE: Update this path before running the script 39 | $PathToOutputCSVReport = "C:\DATA\TagsReport.csv" 40 | 41 | #Adding Azure Account and Subscription 42 | Add-AzureRmAccount 43 | 44 | #Getting all Azure Subscriptions 45 | $subs = Get-AzureRmSubscription 46 | 47 | #Checking if the subscriptions are found or not 48 | if(($subs -ne $null) -or ($subs.Count -gt 0)) 49 | { 50 | #Creating Output Object 51 | $results = @() 52 | 53 | #Iterating over various subscriptions 54 | foreach($sub in $subs) 55 | { 56 | $SubscriptionId = $sub.SubscriptionId 57 | #Selecting the Azure Subscription 58 | Select-AzureRmSubscription -SubscriptionId $SubscriptionId 59 | 60 | #Getting all Azure Resources 61 | $resources = Get-AzureRmResource 62 | 63 | 64 | 65 | foreach($resource in $resources) 66 | { 67 | #Declaring Variables 68 | $TagsAsString = "" 69 | $ApplicationOwner = "" 70 | $ApplicationType = "" 71 | $CostCenter = "" 72 | $Department = "" 73 | $BuildDate = "" 74 | $ApplicationCategory = "" 75 | $CapitalProject = "" 76 | $CapitalProjectName = "" 77 | 78 | #Fetching Tags 79 | $Tags = $resource.Tags 80 | 81 | #Checkign if tags is null or have value 82 | if($Tags -ne $null) 83 | { 84 | 85 | $Tags.GetEnumerator() | % { $TagsAsString += $_.Key + ":" + $_.Value + ";" } 86 | 87 | if($Tags.ContainsKey("ApplicationOwner")) 88 | { 89 | $ApplicationOwner = $Tags["ApplicationOwner"] 90 | } 91 | if($Tags.ContainsKey("Application Owner")) 92 | { 93 | $ApplicationOwner = $Tags["Application Owner"] 94 | } 95 | if($Tags.ContainsKey("ApplicationType")) 96 | { 97 | $ApplicationType = $Tags["ApplicationType"] 98 | } 99 | if($Tags.ContainsKey("Application Type")) 100 | { 101 | $ApplicationType = $Tags["Application Type"] 102 | } 103 | if($Tags.ContainsKey("CostCenter")) 104 | { 105 | $CostCenter = $Tags["CostCenter"] 106 | } 107 | if($Tags.ContainsKey("Cost Center")) 108 | { 109 | $CostCenter = $Tags["Cost Center"] 110 | } 111 | if($Tags.ContainsKey("Department")) 112 | { 113 | $Department = $Tags["Department"] 114 | } 115 | if($Tags.ContainsKey("BuildDate")) 116 | { 117 | $BuildDate = $Tags["BuildDate"] 118 | } 119 | if($Tags.ContainsKey("Build Date")) 120 | { 121 | $BuildDate = $Tags["Build Date"] 122 | } 123 | 124 | } 125 | else 126 | { 127 | $TagsAsString = "NULL" 128 | } 129 | #$results = @() 130 | #Adding to Results 131 | $details = @{ 132 | Name = $resource.Name 133 | ResourceId = $resource.ResourceId 134 | ResourceName = $resource.ResourceName 135 | ResourceType = $resource.ResourceType 136 | ResourceGroupName =$resource.ResourceGroupName 137 | Location = $resource.Location 138 | SubscriptionId = $sub.SubscriptionId 139 | SubscriptionName = $sub.Name 140 | Sku = $resource.Sku 141 | ApplicationOwner = $ApplicationOwner 142 | ApplicationType = $ApplicationType 143 | CostCenter = $CostCenter 144 | Department = $Department 145 | BuildDate = $BuildDate 146 | AllTags = $TagsAsString 147 | } 148 | $results += New-Object PSObject -Property $details 149 | 150 | #Clearing Variable 151 | $TagsAsString = "" 152 | } 153 | } 154 | 155 | $results | export-csv -Path $PathToOutputCSVReport -NoTypeInformation 156 | } 157 | else 158 | { 159 | Write-Host -ForegroundColor Red "No Subscription Found" 160 | } 161 | -------------------------------------------------------------------------------- /Scripts/Tagging Reports/Set-AzureRmTags.ps1: -------------------------------------------------------------------------------- 1 | #Reference Link: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-using-tags 2 | 3 | #Path variable to the CSV file 4 | #NOTE 1: Update this path before running the script 5 | #NOTE 2: Please ensure that the Build Date format in the CSV is dd-MMM-yy 6 | $InputCSVFilePath = "C:\DATA\TagsReportInputs.csv" 7 | 8 | 9 | #Adding Azure Account and Subscription 10 | Add-AzureRmAccount 11 | 12 | $csvContent = Import-Csv -Path $InputCSVFilePath 13 | 14 | Add-AzureRmAccount 15 | 16 | foreach($eachRecord in $csvContent) 17 | { 18 | $ResourceId = $eachRecord.ResourceId 19 | $ResourceGroupName = $eachRecord.ResourceGroupName 20 | $CostCenter = $eachRecord.CostCenter 21 | $ApplicationOwner = $eachRecord.ApplicationOwner 22 | $ApplicationType = $eachRecord.ApplicationType 23 | $Department = $eachRecord.Department 24 | $BuildDate = $eachRecord.BuildDate 25 | $subscriptionName = $eachRecord.SubscriptionName 26 | 27 | if($BuildDate -ne $null) 28 | { 29 | $BuildDate = [datetime]::parseexact($BuildDate, 'dd-MMM-yy', $null).ToString('MM/dd/yy') 30 | } 31 | 32 | #Selecting the Subscription 33 | Select-AzureRmSubscription -SubscriptionName $subscriptionName -ErrorAction Stop 34 | 35 | #Getting Azure Resource 36 | $r = Get-AzureRmResource -ResourceId $ResourceId -ErrorAction Continue 37 | 38 | if($r -ne $null) 39 | { 40 | if($r.tags) 41 | { 42 | # Tag - Cost Center 43 | if($r.Tags.ContainsKey("CostCenter")) 44 | { 45 | $r.Tags["CostCenter"] = $CostCenter 46 | } 47 | else 48 | { 49 | $r.Tags.Add("CostCenter", $CostCenter) 50 | } 51 | 52 | # Tag - Application Owner 53 | if($r.Tags.ContainsKey("ApplicationOwner")) 54 | { 55 | $r.Tags["ApplicationOwner"] = $ApplicationOwner 56 | } 57 | else 58 | { 59 | $r.Tags.Add("ApplicationOwner", $ApplicationOwner) 60 | } 61 | 62 | # Tag - Application Type 63 | if($r.Tags.ContainsKey("ApplicationType")) 64 | { 65 | $r.Tags["ApplicationType"] = $ApplicationType 66 | } 67 | else 68 | { 69 | $r.Tags.Add("ApplicationType", $ApplicationType) 70 | } 71 | 72 | # Tag - Department 73 | if($r.Tags.ContainsKey("Department")) 74 | { 75 | $r.Tags["Department"] = $Department 76 | } 77 | else 78 | { 79 | $r.Tags.Add("Department", $Department) 80 | } 81 | 82 | # Tag - Build Date 83 | if($r.Tags.ContainsKey("BuildDate")) 84 | { 85 | $r.Tags["BuildDate"] = $BuildDate 86 | } 87 | else 88 | { 89 | $r.Tags.Add("BuildDate", $BuildDate) 90 | } 91 | 92 | #Setting the tags on the resource 93 | Set-AzureRmResource -Tag $r.Tags -ResourceId $r.ResourceId -Force 94 | } 95 | else 96 | { 97 | #Setting the tags on a resource which doesn't have tags 98 | Set-AzureRmResource -Tag @{ CostCenter=$CostCenter; ApplicationOwner=$ApplicationOwner; ApplicationType=$ApplicationType; Department=$Department; BuildDate=$BuildDate } -ResourceId $r.ResourceId -Force 99 | } 100 | } 101 | else 102 | { 103 | Write-Host "Resource Not Found with Resource Id: " + $ResourceId 104 | } 105 | } -------------------------------------------------------------------------------- /Scripts/Test-NetworkWatcherRouteNextHop/Input-EnvironmentDetails-ForAutomation.csv: -------------------------------------------------------------------------------- 1 | Source Environment,SourceSubscription,Category,Source Server,Source IP - Indicative,SourceRG,SourceLocation,SourceVMName,Destination Server,DestinationIP-Actual 2 | Dev,Dev-Sub,Azure - Same Region - USE,Dev Web,10.0.0.4,RG-IT-Dev,eastus,accountsdev102,Dev Internal,10.0.2.40 3 | Hub,Hub-Sub,Azure - Same Region - USE,Hub Management,10.1.0.6,RG-Hub,eastus,hubmanage06,Prod Data,10.2.2.20 4 | Dev,Dev-Sub,Internet Connectivity,Dev Data,10.0.0.4,RG-IT-Dev,eastus,accountsdev102,Internet,142.251.41.78 5 | Prod,Prod-Sub,Internet Connectivity,Prod App,10.2.0.10,RG-IT-PROD,eastus,prodvm10,Internet,142.251.41.78 6 | Hub,Hub-Sub,Internet Connectivity,Hub App,10.1.0.6,RG-Hub,eastus,hubmanage06,Internet,142.251.41.78 7 | Dev,Dev-Sub,On Premises,Dev Data,10.0.0.4,RG-IT-Dev,eastus,accountsdev102,On Premises,155.155.10.10 8 | -------------------------------------------------------------------------------- /Scripts/Test-NetworkWatcherRouteNextHop/Test-NetworkWatcherRouteNextHop.ps1: -------------------------------------------------------------------------------- 1 | #Path Variables. Update as per your environment 2 | $InputVMsCSVFilePath = "D:\DATA\RoutesTestEnvironment\Input-EnvironmentDetails-ForAutomation.csv" #Make sure you have updated this CSV as per your environment. This is the INPUT to the script 3 | $PathToOutputCSVReport = "D:\DATA\RoutesTestEnvironment\EnvironmentDetails-ForAutomation-Result.csv" 4 | #Inputs 5 | $subscriptionName = "you-subscription-name" 6 | 7 | try { 8 | 9 | #Adding Azure Account and Subscription 10 | $env = Get-AzEnvironment -Name "AzureCloud" 11 | Connect-AzAccount -Environment $env 12 | Set-AzContext -SubscriptionName $subscriptionName 13 | 14 | #Reading the CSV Content 15 | $csvVMsContent = Import-Csv -Path $InputVMsCSVFilePath 16 | 17 | #Output variable 18 | $outputResults = @() 19 | 20 | foreach($eachVM in $csvVMsContent) 21 | { 22 | #Reading from the input CSV File 23 | $SourceVMSubscriptionName = $eachVM.SourceSubscription 24 | $SourceVMResourceGroupName = $eachVM.SourceRG 25 | $SourceVMName = $eachVM.SourceVMName 26 | $SourceVMIPAddress = $eachVM.'Source IP - Indicative' 27 | $DestinationIPAddress = $eachVM.'DestinationIP-Actual' 28 | $SourceLocation = $eachVM.SourceLocation 29 | 30 | #Setting the Subscription Context 31 | Select-AzSubscription -SubscriptionName $SourceVMSubscriptionName 32 | 33 | #Getting the required variables 34 | $nw = $null 35 | if($SourceLocation -eq "centeralus") 36 | { 37 | $nw = Get-AzNetworkWatcher -Name NetworkWatcher_centralus -ResourceGroupName NetworkWatcherRG 38 | } 39 | else 40 | { 41 | $nw = Get-AzNetworkWatcher -Name NetworkWatcher_eastus2 -ResourceGroupName NetworkWatcherRG 42 | } 43 | 44 | #Fetching the Azure VM 45 | $vm = Get-AzVM -Name $SourceVMName -ResourceGroupName $SourceVMResourceGroupName 46 | 47 | Write-Host "Testing the Source VM $SourceVMName and Destination IP address $DestinationIPAddress." -ForegroundColor Green 48 | #Testing and fetching the next hop 49 | $nextHop = Get-AzNetworkWatcherNextHop -NetworkWatcher $nw -TargetVirtualMachineId $vm.Id -SourceIPAddress $SourceVMIPAddress -DestinationIPAddress $DestinationIPAddress 50 | 51 | #Fetching the results 52 | $eachVM.NextHopType = $nextHop.NextHopType 53 | $eachVM.IPAddressResult = $nextHop.NextHopIpAddress 54 | $eachVM.RouteTableID = $nextHop.RouteTableId 55 | 56 | #Adding to the output 57 | $outputResults += $eachVM 58 | } 59 | $outputResults | export-csv -Path $PathToOutputCSVReport -NoTypeInformation 60 | } 61 | catch { 62 | $ErrorMessage = $_.Exception.Message 63 | Write-Host "ErrorMessage:-" $ErrorMessage -ForegroundColor RED 64 | Break 65 | } 66 | -------------------------------------------------------------------------------- /Scripts/Trigger-AzSAPHANAOnDemandBackup/Trigger-AzSAPHANAOnDemandBackup.ps1: -------------------------------------------------------------------------------- 1 | #Validation - Check the field for "Recovery Point Expiry Time in UTC" in Backup Jobs 2 | #Reference: https://docs.microsoft.com/en-us/azure/backup/tutorial-sap-hana-backup-cli#trigger-an-on-demand-backup 3 | 4 | #region INPUT VARIABLES 5 | $ConfigFilePath = "D:\DATA\Scripts\VMNames - DBs.csv" 6 | 7 | #region Prod Variables 8 | $subscriptionName = "Your-Subscription-Name" 9 | $vaultName = "Your-RecoveryServices-Vault-Name" 10 | $rgOfVault = "RG-of-The-RecoveryServices-Vault" 11 | #endregion 12 | #endregion 13 | 14 | #NOTE: As the script uses both CLI and PowerShell cmdlets, we need to login via both methods and set the context to subscription. This is why you see login twice below. 15 | #Login 16 | az login 17 | # Set the Subscription Context 18 | az account set --subscription $subscriptionName 19 | 20 | #Login in Az Cmdlets 21 | Add-AzAccount 22 | #Set the Subscription Context 23 | Select-AzSubscription -SubscriptionName $subscriptionName 24 | 25 | #Internal custom funtion for checking if the file exists 26 | function Test-FileExists 27 | { 28 | [CmdletBinding()] 29 | PARAM 30 | ( 31 | [Parameter(Mandatory = $true)] 32 | [ValidateNotNullOrEmpty()] 33 | [string]$SourceFile 34 | ) 35 | 36 | try 37 | { 38 | if (Test-Path $SourceFile) 39 | { 40 | Write-Debug " Located: $SourceFile. " 41 | 42 | return $true 43 | } 44 | else 45 | { 46 | Write-Debug " Could not locate: $SourceFile. " 47 | return $false 48 | } 49 | } 50 | catch [system.exception] 51 | { 52 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 53 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 54 | Write-Verbose "Error Details are: " 55 | Write-Verbose $Error[0].ToString() 56 | } 57 | } 58 | 59 | #Check if the config file with VM names exists or not 60 | if(Test-FileExists -SourceFile $ConfigFilePath) 61 | { 62 | try 63 | { 64 | #Importing the CSV File 65 | $configSettings = Import-Csv -Path $ConfigFilePath 66 | 67 | #Setting the Vault Context 68 | $vault = Get-AzRecoveryServicesVault -Name $vaultName -ResourceGroupName $rgOfVault 69 | Set-AzRecoveryServicesVaultContext -Vault $vault 70 | 71 | #Iterating the CSV File 72 | foreach($configSetting in $configSettings) 73 | { 74 | #Setting values 75 | $vmName = $configSetting.VMName 76 | $instanceName = $configSetting.InstanceName 77 | $databasename = $configSetting.DatabaseName 78 | $VMResourceGroup = $configSetting.VMResourceGroup 79 | 80 | #setting item and container variables 81 | $itemName = "SAPHanaDatabase;$instanceName;$databaseName" 82 | $containerName = "VMAppContainer;Compute;$VMResourceGroup;$vmName" 83 | 84 | #Triggering the Backup 85 | #NOTE: This is the AZ CLI Command and not the PowerShell cmdlet, even though we are running it from the PowerShell console 86 | az backup protection backup-now --resource-group $rgOfVault --item-name $itemName --vault-name $vaultName --container-name $containerName --backup-type Full --output table 87 | } 88 | } 89 | catch [system.exception] 90 | { 91 | Write-Verbose "Error : $($_.Exception.Message) " 92 | Write-Host "Error : $($_.Exception.Message) " 93 | Write-Verbose "Error Details are: " 94 | Write-Verbose $Error[0].ToString() 95 | } 96 | } 97 | else 98 | { 99 | Write-Host "Please check the confi file is available at the path specified in the inputs." 100 | } 101 | -------------------------------------------------------------------------------- /Scripts/Trigger-AzSAPHANAOnDemandBackup/VMNames - SAP HANA DBs - Input.csv: -------------------------------------------------------------------------------- 1 | VMName,InstanceName,DatabaseName,VMResourceGroup 2 | AccountsVM102,SID1,pbw,RG-RG-Of-The-VM 3 | AccountsVM102,SID1,systemdb,RG-RG-Of-The-VM 4 | FinanceVM01,SID2,pgr,RG-RG-Of-The-VM 5 | FinanceVM01,SID2,systemdb,RG-RG-Of-The-VM 6 | FinanceVM02,SID2,ppo,RG-RG-Of-The-VM 7 | FinanceVM02,SID2,systemdb,RG-RG-Of-The-VM 8 | FinanceVM03,SID2,ps4,RG-RG-Of-The-VM 9 | FinanceVM03,SID2,systemdb,RG-RG-Of-The-VM 10 | -------------------------------------------------------------------------------- /Scripts/Trigger-AzVMOnDemandBackup/Trigger-AzVMOnDemandBackup.ps1: -------------------------------------------------------------------------------- 1 | #Validation - Check the field for "Recovery Point Expiry Time in UTC" in Backup Jobs 2 | 3 | #Reference: https://docs.microsoft.com/en-us/powershell/module/az.recoveryservices/backup-azrecoveryservicesbackupitem?view=azps-7.1.0 4 | #https://docs.microsoft.com/en-us/azure/backup/quick-backup-vm-powershell#start-a-backup-job 5 | #https://docs.microsoft.com/en-us/azure/backup/powershell-backup-samples 6 | 7 | #region INPUT VARIABLES 8 | #region Environment Variables 9 | $subscriptionName = "Your-Subscription-Name" 10 | $vaultName = "Your-RecoveryServices-Vault-Name" 11 | $rgOfVault = "RG-of-The-RecoveryServices-Vault" 12 | #endregion 13 | 14 | #Expiry of the on-demand VM backup 15 | $dateTillExpiry = Get-Date -Month 12 -Day 18 -Year 2021 -Hour 0 -Minute 0 -Second 0 16 | 17 | #Path of the Config File containing all VM Names for which to trigger the on-demand backup 18 | $ConfigFilePath = "D:\DATA\Scripts\Start-AzureBackup\VMNames-Config.csv" 19 | 20 | #endregion 21 | 22 | #Setting the right context 23 | $env = Get-AzEnvironment -Name "AzureCloud" 24 | Connect-AzAccount -Environment $env 25 | Set-AzContext -SubscriptionName $subscriptionName 26 | 27 | #Internal custom funtion for checking if the file exists 28 | function Test-FileExists 29 | { 30 | [CmdletBinding()] 31 | PARAM 32 | ( 33 | [Parameter(Mandatory = $true)] 34 | [ValidateNotNullOrEmpty()] 35 | [string]$SourceFile 36 | ) 37 | 38 | try 39 | { 40 | if (Test-Path $SourceFile) 41 | { 42 | Write-Debug " Located: $SourceFile. " 43 | 44 | return $true 45 | } 46 | else 47 | { 48 | Write-Debug " Could not locate: $SourceFile. " 49 | return $false 50 | } 51 | } 52 | catch [system.exception] 53 | { 54 | Write-Verbose "Error in Test-FileExists(): $($_.Exception.Message) " 55 | Write-Host "Error in Test-FileExists(): $($_.Exception.Message) " 56 | Write-Verbose "Error Details are: " 57 | Write-Verbose $Error[0].ToString() 58 | } 59 | } 60 | 61 | #Check if the config file with VM names exists or not 62 | if(Test-FileExists -SourceFile $ConfigFilePath) 63 | { 64 | try 65 | { 66 | #Importing the CSV File 67 | $configSettings = Import-Csv -Path $ConfigFilePath 68 | 69 | #Setting the Vault Context 70 | $vault = Get-AzRecoveryServicesVault -Name $vaultName -ResourceGroupName $rgOfVault 71 | #Setting the Recovery Services Vault Context 72 | Set-AzRecoveryServicesVaultContext -Vault $vault 73 | 74 | #Iterating the CSV File 75 | foreach($configSetting in $configSettings) 76 | { 77 | #Getting VM Name from the CSV File 78 | $vmName = $configSetting.VMName 79 | 80 | #Getting the Backup Container 81 | $backupcontainer = Get-AzRecoveryServicesBackupContainer ` 82 | -ContainerType "AzureVM" ` 83 | -FriendlyName $vmName 84 | 85 | #Getting the Backup Item 86 | $item = Get-AzRecoveryServicesBackupItem ` 87 | -Container $backupcontainer ` 88 | -WorkloadType "AzureVM" 89 | 90 | #Triggering the Backups 91 | Backup-AzRecoveryServicesBackupItem -Item $item -ExpiryDateTimeUTC $dateTillExpiry 92 | } 93 | 94 | } 95 | catch [system.exception] 96 | { 97 | Write-Verbose "Error : $($_.Exception.Message) " 98 | Write-Host "Error : $($_.Exception.Message) " 99 | Write-Verbose "Error Details are: " 100 | Write-Verbose $Error[0].ToString() 101 | } 102 | } 103 | else 104 | { 105 | Write-Host "Please check the confi file is available at the path specified in the inputs." 106 | } 107 | -------------------------------------------------------------------------------- /Scripts/Trigger-AzVMOnDemandBackup/VMNames - Input - Sample.csv: -------------------------------------------------------------------------------- 1 | VMName 2 | AccountsVM101 3 | AccountsVM102 4 | FinanceVM01 5 | FinanceVM02 6 | FinanceVM03 7 | FinanceVM04 8 | FinanceVM05 9 | FinanceVM06 10 | -------------------------------------------------------------------------------- /Scripts/Update-CustomRoleSample/Update-CustomRoleSample.ps1: -------------------------------------------------------------------------------- 1 | $SubscriptionName = "SubscriptionName" 2 | $roleName = "Virtual Machine Operator" 3 | 4 | #region Loggin in and selecting Subscription 5 | Add-AzureRmAccount 6 | 7 | Select-AzureRmSubscription -SubscriptionName $SubscriptionName 8 | 9 | #endregion 10 | 11 | #View existing Azure Role Definition 12 | Get-AzureRMRoleDefinition -Name $roleName | ConvertTo-Json 13 | 14 | #Fetching the existing Role 15 | $role = Get-AzureRmRoleDefinition $roleName 16 | 17 | #Updating the existing Role 18 | $role.Actions.Add("Microsoft.Compute/virtualMachines/deallocate/action") 19 | $role.Description = "Can monitor, Start, Stop and restart virtual machines." 20 | 21 | #Setting the updates back to the Azure 22 | Set-AzureRmRoleDefinition -Role $role -------------------------------------------------------------------------------- /Scripts/User Defined Routes (UDRs) or Route Tables Related Scripts/Associate-SubnetsToUDRs - input.csv: -------------------------------------------------------------------------------- 1 | vNetResourceGroupName,subnetAddressPrefix,subnetName,virtualNetworkName,routeTableName,routeResourceGroup,subscriptionId 2 | RGName1,10.10.0.0/24,Subnet1,vNet1,RouteTable1,RouteTableRGName1,aaaaaaa-1111-1111-1111-aaaaaaaaaaaa 3 | RGName1,10.11.0.0/24,Subnet2,vNet1,RouteTable1,RouteTableRGName1,aaaaaaa-1111-1111-1111-aaaaaaaaaaaa 4 | RGName2,10.12.0.0/24,Subnet3,vNet1,RouteTable2,RouteTableRGName2,aaaaaaa-1111-1111-1111-aaaaaaaaaaaa 5 | -------------------------------------------------------------------------------- /Scripts/User Defined Routes (UDRs) or Route Tables Related Scripts/Associate-SubnetsToUDRs.ps1: -------------------------------------------------------------------------------- 1 | $UDRsCSVFilePath = "C:\DATA\Associate-SubnetsToUDRs - input.csv" 2 | 3 | #Importing the CSV file Content 4 | $csvUDRsContent = Import-Csv -Path $UDRsCSVFilePath 5 | 6 | Add-AzureRmAccount 7 | 8 | foreach($eachUDR in $csvUDRsContent) 9 | { 10 | $routeTableName = $eachUDR.routeTableName 11 | $addressPrefix = $eachUDR.subnetAddressPrefix 12 | $deploymentName = "deployment-"+$routeTableName 13 | $subscriptionId = $eachUDR.subscriptionId 14 | $routeResourceGroupName = $eachUDR.routeResourceGroup 15 | 16 | $subnetName = $eachUDR.subnetName 17 | $subnetAddressPrefix = $eachUDR.subnetAddressPrefix 18 | $vNetOfSubnet = $eachUDR.virtualNetworkName 19 | $vNetResourceGroupName = $eachUDR.vNetResourceGroupName 20 | 21 | Select-AzureRmSubscription -SubscriptionId $subscriptionId 22 | 23 | $virtualNetwork = Get-AzureRmVirtualNetwork -Name $vNetOfSubnet -ResourceGroupName $vNetResourceGroupName 24 | 25 | $routeTable = $null 26 | $routeTable = Get-AzureRmRouteTable -Name $routeTableName -ResourceGroupName $routeResourceGroupName 27 | 28 | 29 | Set-AzureRmVirtualNetworkSubnetConfig ` 30 | -Name $subnetName ` 31 | -VirtualNetwork $virtualNetwork ` 32 | -AddressPrefix $subnetAddressPrefix ` 33 | -RouteTable $routeTable | 34 | Set-AzureRmVirtualNetwork 35 | 36 | } -------------------------------------------------------------------------------- /Scripts/User Defined Routes (UDRs) or Route Tables Related Scripts/Disassociate-SubnetsFromUDRs.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Microsoft Corporation. All rights reserved. 5 | 6 | File: Disassociate-SubnetsFromUDRs.ps1 7 | 8 | Purpose: To get the report for tags of all the resources in Azure 9 | 10 | Version: 1.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Disassociate Subnets from Route Tables 16 | 17 | .DESCRIPTION 18 | This script is used to disassociate subnets from route tables. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Disassociate-SubnetsFromUDRs.ps1 22 | 23 | Description 24 | ----------- 25 | This command executes the script with default parameters. 26 | 27 | .INPUTS 28 | None. 29 | 30 | .OUTPUTS 31 | None. 32 | 33 | .LINK 34 | None. 35 | #> 36 | 37 | #Adding Azure Account and Subscription 38 | Add-AzureRmAccount 39 | 40 | #Getting all Azure Subscriptions 41 | $subs = Get-AzureRmSubscription 42 | 43 | #Checking if the subscriptions are found or not 44 | if(($subs -ne $null) -or ($subs.Count -gt 0)) 45 | { 46 | #Iterating over various subscriptions 47 | foreach($sub in $subs) 48 | { 49 | $SubscriptionId = $sub.SubscriptionId 50 | Write-Output $SubscriptionName 51 | 52 | #Selecting the Azure Subscription 53 | Select-AzureRmSubscription -SubscriptionName $SubscriptionId 54 | 55 | #Getting all Azure Route Tables 56 | $routeTables = Get-AzureRmRouteTable 57 | 58 | foreach($routeTable in $routeTables) 59 | { 60 | $routeName = $routeTable.Name 61 | Write-Output $routeName 62 | 63 | #Fetch Route Subnets 64 | $routeSubnets = $routeTable.Subnets 65 | 66 | foreach($routeSubnet in $routeSubnets) 67 | { 68 | $subnetName = $routeSubnet.Name 69 | Write-Output $subnetName 70 | 71 | $subnetId = $routeSubnet.Id 72 | 73 | ###Getting information 74 | $splitarray = $subnetId.Split('/') 75 | $subscriptionId = $splitarray[2] 76 | $vNetResourceGroupName = $splitarray[4] 77 | $virtualNetworkName = $splitarray[8] 78 | $subnetName = $splitarray[10] 79 | 80 | #$subnet = Get-AzureRmResource -ResourceId $subnetId 81 | write-output $subnet.Name 82 | ####$NSG=Get-AzureRmNetworkSecurityGroup | where { $_.ID -eq $NSGid } 83 | 84 | $virtualNetwork = Get-AzureRmVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $vNetResourceGroupName 85 | 86 | $subnet = $virtualNetwork.Subnets | where {$_.Name -eq $subnetName} 87 | 88 | #### Setting the Route table to Null 89 | $subnet.RouteTable = $null 90 | 91 | $subnetAddressPrefix = $subnet.AddressPrefix 92 | 93 | #Setting and committing the changes 94 | Set-AzureRmVirtualNetworkSubnetConfig ` 95 | -Name $subnetName ` 96 | -VirtualNetwork $virtualNetwork ` 97 | -AddressPrefix $subnetAddressPrefix ` 98 | -RouteTable $null | 99 | Set-AzureRmVirtualNetwork 100 | 101 | } 102 | 103 | } 104 | } 105 | 106 | } 107 | else 108 | { 109 | Write-Host -ForegroundColor Red "No Subscription Found" 110 | } 111 | -------------------------------------------------------------------------------- /Scripts/User Defined Routes (UDRs) or Route Tables Related Scripts/Report-UDRsWithSubnetInfo.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NOTES 3 | ============================================================================================== 4 | Copyright (c) Microsoft Corporation. All rights reserved. 5 | 6 | File: Report-UDRsWithSubnetInfo.ps1 7 | 8 | Purpose: To get the report for tags of all the resources in Azure 9 | 10 | Version: 1.0.0.0 11 | 12 | Author: Aman Sharma 13 | ============================================================================================== 14 | .SYNOPSIS 15 | Disassociate Subnets from Route Tables 16 | 17 | .DESCRIPTION 18 | This script is used to disassociate subnets from route tables. 19 | 20 | .EXAMPLE 21 | C:\PS> .\Report-UDRsWithSubnetInfo.ps1 22 | 23 | Description 24 | ----------- 25 | This command executes the script with default parameters. 26 | 27 | .INPUTS 28 | None. 29 | 30 | .OUTPUTS 31 | None. 32 | 33 | .LINK 34 | None. 35 | #> 36 | 37 | $PathToOutputCSVReport = "C:\DATA\report.csv" 38 | 39 | #Adding Azure Account and Subscription 40 | Add-AzAccount 41 | 42 | #Getting all Azure Subscriptions 43 | $subs = Get-AzSubscription 44 | 45 | #Checking if the subscriptions are found or not 46 | if(($subs -ne $null) -or ($subs.Count -gt 0)) 47 | { 48 | #Creating Output Object 49 | $results = @() 50 | 51 | #Iterating over various subscriptions 52 | foreach($sub in $subs) 53 | { 54 | $SubscriptionId = $sub.SubscriptionId 55 | Write-Output $SubscriptionName 56 | 57 | #Selecting the Azure Subscription 58 | Select-AzSubscription -SubscriptionName $SubscriptionId 59 | 60 | #Getting all Azure Route Tables 61 | $routeTables = Get-AzRouteTable 62 | 63 | foreach($routeTable in $routeTables) 64 | { 65 | $routeTableName = $routeTable.Name 66 | $routeResourceGroup = $routeTable.ResourceGroupName 67 | Write-Output $routeName 68 | 69 | #Fetch Route Subnets 70 | $routeSubnets = $routeTable.Subnets 71 | 72 | foreach($routeSubnet in $routeSubnets) 73 | { 74 | $subnetName = $routeSubnet.Name 75 | Write-Output $subnetName 76 | 77 | $subnetId = $routeSubnet.Id 78 | 79 | ###Getting information 80 | $splitarray = $subnetId.Split('/') 81 | $subscriptionId = $splitarray[2] 82 | $vNetResourceGroupName = $splitarray[4] 83 | $virtualNetworkName = $splitarray[8] 84 | $subnetName = $splitarray[10] 85 | 86 | #Fetching the vNet and Subnet details 87 | $vnet = Get-AzVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $vNetResourceGroupName 88 | $subnet = Get-AzVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $vnet 89 | 90 | $subnetAddressPrefix = $subnet.AddressPrefix[0] 91 | 92 | $details = @{ 93 | routeTableName=$routeTableName 94 | routeResourceGroup=$routeResourceGroup 95 | subnetName=$subnetName 96 | subscriptionId=$subscriptionId 97 | vNetResourceGroupName=$vNetResourceGroupName 98 | virtualNetworkName=$virtualNetworkName 99 | subnetAddressPrefix=$subnetAddressPrefix 100 | } 101 | $results += New-Object PSObject -Property $details 102 | 103 | 104 | } 105 | 106 | } 107 | } 108 | $results | export-csv -Path $PathToOutputCSVReport -NoTypeInformation 109 | } 110 | else 111 | { 112 | Write-Host -ForegroundColor Red "No Subscription Found" 113 | } 114 | -------------------------------------------------------------------------------- /Scripts/Working with Azure VM Snapshots/Copy-SnapshotToStorage.ps1: -------------------------------------------------------------------------------- 1 |  2 | $storageAccountName = "sttemp01" 3 | $storageAccountKey = "YourKey" 4 | $absoluteUri = "https://StorageAccountName.blob.core.windows.net/ContainerName/abcd?sv=2017-04-17&sr=b&si=aaaaaaaa-1111-1111-1111-aaaaaaaa&sig=signature" 5 | $destContainer = "vhds" 6 | $blobName = "VMName-osdisk.vhd" 7 | 8 | $destContext = New-AzureStorageContext –StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey 9 | $targetBlob = Start-AzureStorageBlobCopy -AbsoluteUri $absoluteUri -DestContainer $destContainer -DestContext $destContext -DestBlob $blobName 10 | 11 | $targetBlob = Get-AzureStorageBlob -Blob $blobName -Container $destContainer -Context $destContext 12 | 13 | $copyState = $targetBlob | Get-AzureStorageBlobCopyState 14 | 15 | while ($copyState.Status -ne "Success") 16 | { 17 | $percent = ($copyState.BytesCopied / $copyState.TotalBytes) * 100 18 | Write-Host "Completed $('{0:N2}' -f $percent)%" 19 | sleep -Seconds 20 20 | $copyState = $targetBlob | Get-AzureStorageBlobCopyState 21 | } -------------------------------------------------------------------------------- /Scripts/Working with Azure VM Snapshots/Create-VMFromSnapshot.ps1: -------------------------------------------------------------------------------- 1 | #Logging into Azure 2 | Add-AzureRmAccount 3 | 4 | Select-AzureRmSubscription -SubscriptionName "Subscription Name" 5 | 6 | #Prepare the VM parameters 7 | $rgName = "Resource Group Name" 8 | $location = "eastus2" 9 | $vnet = "vNet-Name-USE2" 10 | $subnet = "/subscriptions/aaaaaaa-1111-1111-1111-aaaaaaaaa/resourceGroups/RG-Dev-USE2/providers/Microsoft.Network/virtualNetworks/vNet-Name-USE2/subnets/sNet-Name-USE2" 11 | $nicName = "VMName-nic" 12 | $vmName = "VMName" 13 | $osDiskName = "VMName-osdisk" 14 | $osDiskUri = "https://StorageAccountName.blob.core.windows.net/vhds/VMName-osdisk.vhd" 15 | $VMSize = "Standard_F8s_v2" 16 | $storageAccountType = "StandardLRS" 17 | $IPaddress = "192.168.0.5" 18 | 19 | #Create the VM resources 20 | $IPconfig = New-AzureRmNetworkInterfaceIpConfig -Name "IPConfig1" -PrivateIpAddressVersion IPv4 -PrivateIpAddress $IPaddress -SubnetId $subnet 21 | $nic = New-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $location -IpConfiguration $IPconfig 22 | $vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize $VMSize 23 | $vm = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $nic.Id 24 | 25 | $osDisk = New-AzureRmDisk -DiskName $osDiskName -Disk (New-AzureRmDiskConfig -AccountType $storageAccountType -Location $location -CreateOption Import -SourceUri $osDiskUri) -ResourceGroupName $rgName 26 | $vm = Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $osDisk.Id -StorageAccountType $storageAccountType -DiskSizeInGB 128 -CreateOption Attach -Windows 27 | $vm = Set-AzureRmVMBootDiagnostics -VM $vm -disable 28 | 29 | #Create the new VM 30 | New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm -LicenseType "Windows_Server" --------------------------------------------------------------------------------