<# .Synopsis Sets Common Permissions on a Resource Group depending on Ownershiptest .DESCRIPTION Long description .EXAMPLE Set-ITDAzureRMResourceGroupAssignment -Ownership VM -ResourceGroup rg-itd-resourcegroup-tst .EXAMPLE Set-ITDAzureRMResourceGroupAssignment -Ownership Network -ResourceGroup rg-itd-netresourcegroup-tst #> function Set-ITDAzureRMResourceGroupAssignment { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, Position=0)] [String] $Ownership, # Param2 help description [Parameter(Mandatory=$true,Position=1)] [string] $ResourceGroup ) Begin { $Tenant = (Get-AzureRMContext).Environment.Name } Process { If ($Ownership -eq "VM"){ If($Tenant -eq "AzureUSGovernment") { $ADGroupOperator = Get-AzureRMADGroup -SearchString "ITD-MAG-VM-Operator" $ADGroupContributor = Get-AzureRMADGroup -SearchString "ITD-MAG-VM-Contributor" } Elseif($Tenant -eq "AzureCloud") { $ADGroupOperator = Get-AzureRMADGroup -SearchString "ITD-MAC-VM-Operator" $ADGroupContributor = Get-AzureRMADGroup -SearchString "ITD-MAC-VM-Contributor" } New-AzureRMRoleAssignment -ObjectID $ADGroupOperator.Id.ToString() -RoleDefinitionName "ITD-VM-Operator" -ResourceGroup $ResourceGroup New-AzureRMRoleAssignment -ObjectID $ADGroupContributor.Id.ToString() -RoleDefinitionName "ITD-VM-Contributor" -ResourceGroup $ResourceGroup } If ($Ownership -eq "Network"){ If($Tenant -eq "AzureUSGovernment") { $ADGroupOperator = Get-AzureRMADGroup -SearchString "ITD-MAG-Network-Operator" $ADGroupContributor = Get-AzureRMADGroup -SearchString "ITD-MAG-Network-Contributor" } Elseif($Tenant -eq "AzureCloud") { $ADGroupOperator = Get-AzureRMADGroup -SearchString "ITD-MAC-Network-Operator" $ADGroupContributor = Get-AzureRMADGroup -SearchString "ITD-MAC-Network-Contributor" } New-AzureRMRoleAssignment -ObjectID $ADGroupOperator.Id.ToString() -RoleDefinitionName "ITD-VM-Operator" -ResourceGroup $ResourceGroup New-AzureRMRoleAssignment -ObjectID $ADGroupContributor.Id.ToString() -RoleDefinitionName "ITD-VM-Contributor" -ResourceGroup $ResourceGroup } } End { } } <# .Synopsis Gets all Azure IP's Across MAC and MAG and outputs to text files .DESCRIPTION Long description .EXAMPLE Get-ITDAzureRMIPs -OutputPath "C:\temp" .EXAMPLE Example2 #> function Get-ITDAzureRMIPs { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, Position=0)] [String] $OutputPath ) Begin { $WindowsIPs = "" $LinuxIPs = "" $OutFileWin = $OutputPath + "\AzureWin.txt" $OutFileLin = $OutputPath + "\AzureLin.txt" } Process { Login-AzureRMAccount $Subscriptions = Get-AzureRMSubscription | Where-Object {$_.Name -ne "sandbox"} foreach($subscription in $subscriptions) { Set-AzureRMContext -SubscriptionObject $subscription $WindowsVMs = Get-AzureRMVM | Where-Object {$_.StorageProfile.osdisk.ostype -match "Windows"} $LinuxVMs = Get-AzureRMVM | Where-Object {$_.StorageProfile.osdisk.ostype -match "Linux" -and $_.StorageProfile.ImageReference.Publisher -ne "infoblox" -and $_.StorageProfile.ImageReference.Publisher -ne "paloaltonetworks" -and $_.StorageProfile.ImageReference.Publisher -ne "juniper-networks"} $nics = Get-AzureRMNetworkInterface | Where-Object {$_.VirtualMachine -NE $null} foreach($vm in $WindowsVMs) { $vmnicinterfaces = $vm.Networkprofile.NetworkInterfaces.id foreach($vmnicinterface in $vmnicinterfaces) { $nic = $nics | Where-Object {$_.Id -eq $vmnicinterface} $privateip = $nic.IpConfigurations | Select PrivateIPAddress If($privateip.count -gt 1) { foreach($private in $privateip) { $WindowsIPs += $private.privateIPAddress + "`n" } } elseIf($privateip.privateIPAddress -ne $null) { $WindowsIPs += $privateip.privateIPAddress + "`n" } } } foreach($vm in $LinuxVMs) { $vmnicinterfaces = $vm.Networkprofile.NetworkInterfaces.id foreach($vmnicinterface in $vmnicinterfaces) { $nic = $nics | Where-Object {$_.Id -eq $vmnicinterface} $privateip = $nic.IpConfigurations | Select PrivateIPAddress If($privateip.count -gt 1) { foreach($private in $privateip) { $LinuxIPs += $private.privateIPAddress + "`n" } } elseif($privateip.privateIPAddress -ne $null) { $LinuxIps += $privateip.privateIPAddress + "`n" } } } } Login-AzureRMAccount -EnvironmentName AzureUSGovernment $Subscriptions = Get-AzureRMSubscription | Where-Object {$_.Name -ne "sandbox"} foreach($subscription in $subscriptions) { Set-AzureRMContext -SubscriptionObject $subscription $WindowsVMs = Get-AzureRMVM | Where-Object {$_.StorageProfile.osdisk.ostype -match "Windows"} $LinuxVMs = Get-AzureRMVM | Where-Object {$_.StorageProfile.osdisk.ostype -match "Linux" -and $_.StorageProfile.ImageReference.Publisher -ne "infoblox" -and $_.StorageProfile.ImageReference.Publisher -ne "paloaltonetworks" -and $_.StorageProfile.ImageReference.Publisher -ne "juniper-networks"} $nics = Get-AzureRMNetworkInterface | Where-Object {$_.VirtualMachine -NE $null} foreach($vm in $WindowsVMs) { $vmnicinterfaces = $vm.Networkprofile.NetworkInterfaces.id foreach($vmnicinterface in $vmnicinterfaces) { $nic = $nics | Where-Object {$_.Id -eq $vmnicinterface} $privateip = $nic.IpConfigurations | Select PrivateIPAddress If($privateip.count -gt 1) { foreach($private in $privateip) { $WindowsIPs += $private.privateIPAddress + "`n" } } elseIf($privateip.privateIPAddress -ne $null) { $WindowsIPs += $privateip.privateIPAddress + "`n" } } } foreach($vm in $LinuxVMs) { $vmnicinterfaces = $vm.Networkprofile.NetworkInterfaces.id foreach($vmnicinterface in $vmnicinterfaces) { $nic = $nics | Where-Object {$_.Id -eq $vmnicinterface} $privateip = $nic.IpConfigurations | Select PrivateIPAddress If($privateip.count -gt 1) { foreach($private in $privateip) { $LinuxIPs += $private.privateIPAddress + "`n" } } elseif($privateip.privateIPAddress -ne $null) { $LinuxIps += $privateip.privateIPAddress + "`n" } } } } If ($WindowsIPs -ne "") {$WindowsIPs | Out-File $OutFileWin -Encoding ASCII -NoNewline} If ($LinuxIPs -ne "") {$LinuxIPs | Out-File $OutFileLin -Encoding ASCII -NoNewline} } End { } } function Set-ITDAzureRMResourceGroupTags { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Resouce Group [String] $ResourceGroup, # Tag Hash Table [HashTable] $TagHashTable, # Input File [String] $InputFile ) Begin { } Process { If($InputFile) { $filetable = Import-CSV -Path $InputFile foreach($record in $filetable) { $TagHashTable = @{} $TagHashTable.Add("Environment",$record.Environment) $TagHashTable.Add("Platform",$record.Platform) $TagHashTable.Add("RequestID",$record.RequestID) $TagHashTable.Add("Division",$record.Division) $TagHashTable.Add("ApplicationName",$record.ApplicationName) $TagHashTable.Add("ChargeCode",$record.ChargeCode) $TagHashTable.Add("Department",$record.Department) Set-AzureRmContext $record.Subscription Set-ITDAzureRMResourceGroupTags -ResourceGroup $record.ResourceGroup -TagHashTable $TagHashTable } Return } #Get Current Tags from Resource Group $GroupTags = (Get-AzureRmResourceGroup -Name $ResourceGroup).Tags #Identify Duplicate Tags. Remove Duplicates from Original Tags in Case of Conflict $DuplicateItems = $GroupTags.Keys | Where-Object {$TagHashTable.ContainsKey($_)} If ($DuplicateItems) { ForEach ($DuplicateKey in $DuplicateItems){ $GroupTags.Remove($DuplicateKey) } } #Merge Hashtables and Write Table back to Resource Group $GroupTags += $TagHashTable Set-AzureRmResourceGroup -Name $ResourceGroup -Tag $GroupTags #Get All Resources in the Resource Group $Resources = Get-AzureRmResource | Where-Object {$_.ResourceGroupName -eq $ResourceGroup -and $_.ResourceType -notmatch "Microsoft.Compute/virtualMachines/extensions"} ForEach ($Resource in $Resources){ $ResourceTags = $Resource.Tags #Identify Duplicate Tags. Remove Duplicates from Original Tags in Case of Conflict $DuplicateItems = $ResourceTags.Keys | Where-Object {$TagHashTable.ContainsKey($_)} If ($DuplicateItems) { ForEach ($DuplicateKey in $DuplicateItems){ $ResourceTags.Remove($DuplicateKey) } } #Merge Hashtables and Write Table back to Resource $ResourceTags += $TagHashTable Set-AzureRMResource -ResourceID $Resource.ResourceID -Tag $ResourceTags -Confirm:$false -Force } } End { } } function Set-ITDAzureRMResourceGroupTagsRefresh { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Resouce Group [String] $ResourceGroup ) Begin { $TagHashTable = @{} $TagHashTable = (Get-AzureRMResourceGroup -Name $ResourceGroup ).Tags } Process { Set-ITDAzureRMResourceGroupTags -ResourceGroup $ResourceGroup -TagHashTable $TagHashTable } End { } } function New-ITDAzureRMPolicyDefinition { [OutputType([int])] Param ( # Resource Group [Parameter(Mandatory=$true, Position=0)] [Array] $Environments, # Policy Name Prefix [Parameter(Mandatory=$true, Position=1)] [String] $prefix, # Policy Name Suffix [Parameter(Mandatory=$true, Position=2)] [String] $suffix, # Policy in String Format (If...Then Components) [Parameter(Mandatory=$true,Position=3)] [String] $Policy ) Begin { } Process { Foreach ($environment in $Environments){ Set-AzureRMContext $environment $policyname = $prefix + $environment + $suffix New-AzureRmPolicyDefinition -Name $policyname -Policy $Policy } } End { } } function Find-ITDAzureRMUntaggedResources { [OutputType([int])] Param ( # Resource Group [Parameter(Mandatory=$false, Position=0)] [String] $TagName ) Begin { $subscriptions = @() $untaggedresources = @() } Process { #$subscriptions = Get-AzureRMSubscription | WHere-Object {$_.name -ne "sandbox"} $subscriptions = Get-AzureRMSubscription Foreach ($subscription in $subscriptions){ Set-AzureRMContext $subscription $resources = Get-AzureRMResource ForEach ($resource in $resources){ If ($resource.tags -ne $null){ If (($resource.tags.contains("Department") -eq $false) -or ($resource.tags.contains("ApplicationName") -eq $false) -or ($resource.tags.contains("Environment") -eq $false) -or ($resource.tags.contains("RequestID") -eq $false)){ $untaggedresources += $resource } } Else { $untaggedresources += $resource } } } $untaggedresources | Select Name, ResourceGroupName, SubscriptionID | Sort-Object SubscriptionID, ResourceGroupname, Name | Format-Table } End { } } <# .Synopsis Creates an Azure VM. .DESCRIPTION Long description .EXAMPLE New-ITDAzureRMVM -VMName itdcdtest -VMSubscription npd01 -VMEnvironment tst -VMOwner shared -VMFunction cdtesting -VMSize Standard_A2 -VMOS Windows -VMPublisher MicrosoftWindowsServer -VMOffer WindowsServer -VMSku 2016-Datacenter -VMVNetName vnet-tst-npd01-001 -VMSubnet "sn-10.21.20.0_28" -VMLocation centralUS -VMIP "10.21.20.10" .EXAMPLE #> function New-ITDAzureRMVM { [CmdletBinding()] Param ( # VM Computer Name (FQDN) [Parameter(Mandatory=$true, Position=0)] [String] $VMFQDN, # VM Subscription (tst,prd,dr) [Parameter(Mandatory=$true)] [string] $VMSubscription, # Environment (tst,prd,dr) [Parameter(Mandatory=$true)] [string] $VMEnvironment, # Owner (infra,shared,ITD,DHS,etc) [Parameter(Mandatory=$true)] [string] $VMOwner, # Function (testdc, POC, etc) [Parameter(Mandatory=$true)] [string] $VMFunction, #[Parameter(Mandatory=$true)] [string] $ResourceGroupIndexNumber, # Azure VM Size [Parameter(Mandatory=$true)] [string] $VMSize, # Azure OS (Windows or Linux) [Parameter(Mandatory=$true)] [string] $VMOS, # Availability Set [switch] $VMAS, # Availability Set Tier [string] $VMASTier, # Availability Zone [ValidateSet(1,2,3)] [int] $VMAvailZone, # Azure Publisher [string] $VMPublisher, # Azure Offer [string] $VMOffer, # Azure Sku [string] $VMSku, # Azure vNet [Parameter(Mandatory=$true)] [string] $VMVNetName, # Azure Subnet [Parameter(Mandatory=$true)] [string] $VMSubnet, # Azure Location [Parameter(Mandatory=$true)] [string] $VMLocation, # Azure Private IP [Parameter(Mandatory=$true)] [string] $VMIP, [Parameter(Mandatory=$true)] [PSCredential] $VMCredential ) Begin { $VMName = $VMFQDN.Split('.')[0] $VMIndexNumber = "001" $VMIPConfigName = "ipconfig-$VMName-$VMEnvironment" $VMNicName = "nic-$VMName-$VMEnvironment" ###### $VMObjectName = "vm-$VMName-$VMEnvironment" $ResourceGroup = "rg-$VMOwner-$VMFunction-$VMEnvironment" If($ResourceGroupIndexNumber){$ResourceGroup = $ResourceGroup + "-$ResourceGroupIndexNumber"} $VMDiagStorageAcct = "sa" + $VMOwner + $VMFunction + "diag" + $VMEnvironment $VMOSDiskName = "vm-$VMName-os-$VMEnvironment" If($VMASTier) { $VMASName = "as-$VMOwner-$VMFunction-$VMASTier-$VMEnvironment" } Else { $VMASName = "as-$VMOwner-$VMFunction-$VMEnvironment" } $ResGroupExist = "" Write-Verbose "Checking Storage Account Length" If (($VmDiagStorageAcct.Length) -gt 24){ Write-Verbose "Storage Account Length is too long. Truncating function...." $TruncateCharacters = $VmDiagStorageAcct.Length - 24 $ShortVMFunction = $VMFunction.Substring(0, ($VMFunction.length) - $TruncateCharacters) $VMDiagStorageAcct = "sa" + $VMOwner + $ShortVMFunction + "diag" + $VMEnvironment } If (($VmDiagStorageAcct.Length) -gt 24){ Write-Verbose "Storage Account Length is too long after truncating. Terminating Build" Return } Write-Verbose "Verifying Applicable Inputs are Lowercase" $VMIPConfigName = $VMIPConfigName.ToLower() $VMNicName = $VMNicName.ToLower() $VMObjectName = $VMObjectName.ToLower() $ResourceGroup = $ResourceGroup.ToLower() $VMDiagStorageAcct = $VMDiagStorageAcct.ToLower() $VMOSDiskName = $VMOSDiskName.ToLower() } Process { Set-AzureRMContext $VMSubscription Write-Verbose "Creating Resource Group if it doesn't exist" $ResGroupExist = Get-AzureRMResourceGroup -Name $ResourceGroup -ErrorAction SilentlyContinue If (!($ResGroupExist)) { New-AzureRmResourceGroup -Name $ResourceGroup -Location $VMLocation } Write-Verbose "Checking Storage Account Availability in Subscription" If (!(Get-AzureRmStorageAccount | Where-Object {$_.StorageAccountName -eq $VMDiagStorageAcct})) { If ((Get-AzureRmStorageAccountNameAvailability -Name $VMDiagStorageAcct).NameAvailable -eq $True) { New-AzureRmStorageAccount -Name $VMDiagStorageAcct -Location $VMLocation -ResourceGroupName $ResourceGroup -SkuName "Standard_LRS" -EnableHttpsTrafficOnly $true #Start-Sleep -Seconds 5 Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroup -Name $VMDiagStorageAcct | Update-AzureRmStorageAccountNetworkRuleSet -DefaultAction Deny -Bypass None #Update-AzureRmStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroup -Name $VMDiagStorageAcct -DefaultAction Deny -Bypass None Add-AzureRmStorageAccountNetworkRule -ResourceGroupName $ResourceGroup -AccountName $VMDiagStorageAcct -IPAddressOrRange "165.234.248.3" } Else { Write-Verbose "Storage Account already exists. Re-run with a valid storage account" Return } } Write-Verbose "Evaluating Availability Set" If($VMAS) { Write-Verbose "Checking for existing Availability Set" $VMASExist = Get-AzureRMAvailabilitySet -ResourceGroupName $ResourceGroup -Name $VMASName -ErrorAction SilentlyContinue If($VMASExisting) { $VMASID = $VMASExist.id } Else { New-AzureRMAvailabilitySet -ResourceGroupName $ResourceGroup -Name $VMASName -Location $VMLocation -PlatformFaultDomainCount 3 -PlatformUpdateDomainCount 5 -Sku Aligned $VMASID = (Get-AzureRMAvailabilitySet -ResourceGroupName $ResourceGroup -Name $VMASName).id } } Write-Verbose "Preparing Network Config" $VNet = (Get-AzureRmVirtualNetwork | where {$_.Name -eq $VMVNetName}) $VNetID = $VNet.id $Subnet = ($VNet.Subnets | where {$_.Name -eq $VMSubnet}) $SubnetName = $Subnet.name $SubnetID = $Subnet.id Write-Verbose "Creating IPConfig and NIC" $IPConfig = New-AzureRmNetworkInterfaceIpConfig -Name $VMIPConfigName -PrivateIpAddress $VMIP -PrivateIpAddressVersion IPv4 -Subnet $Subnet $VMNIC = New-AzureRmNetworkInterface -IpConfigurationName $IPConfig -Location $VMLocation -Name $VMNICName -ResourceGroupName $ResourceGroup -SubnetId $SubnetID $VMNIC.IpConfigurations[0].PrivateIpAllocationMethod = "Static" $VMNIC.IpConfigurations[0].PrivateIpAddress = $VMIP Set-AzureRmNetworkInterface -NetworkInterface $VMNIC Write-Verbose "Building VM Config" If($VMAS) { $vmConfig = New-AzureRmVMConfig -VMName $VMObjectName -VMSize $VMSize -AvailabilitySetId $VMASID } Else { If($VMAvailZone) { Write-Verbose "AvailZone $VMAvailZone" $vmConfigParams = @{ VMName = $VMObjectName VMSize = $VMSize Zone = $VMAvailZone } } Else { Write-Verbose "No AvailZone" $vmConfigParams = @{ VMName = $VMObjectName VMSize = $VMSize } } #$vmConfig = New-AzureRmVMConfig -VMName $VMObjectName -VMSize $VMSize $vmConfig = New-AzureRmVMConfig @vmConfigParams } $vmConfig | Set-AzureRmVMOSDisk -Name $VMOSDiskName -CreateOption FromImage If($VMOS -eq "Windows") { $vmConfig | Set-AzureRmVMOperatingSystem -Windows -ComputerName $VMName -Credential $VMCredential $vmConfig | Set-AzureRmVMSourceImage -PublisherName $VMPublisher -Offer $VMOffer -Skus $VMSku -Version latest } If($VMOS -eq "Linux") { $vmConfig | Set-AzureRmVMOperatingSystem -Linux -ComputerName $VMFQDN -Credential $VMCredential Switch($VMSubscription) { #"npd01" {$vmConfig | Set-AzureRmVMSourceImage -Id "/subscriptions/76297098-764c-43de-8525-c9fda1b237be/resourceGroups/rg-infra-templates-tst-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-001"} #"infra01" {$vmConfig | Set-AzureRmVMSourceImage -Id "/subscriptions/e53aa0c7-824d-40a2-b420-4ab77b1051d2/resourceGroups/rg-infra-templates-prd-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-001"} #"prd01" {$vmConfig | Set-AzureRmVMSourceImage -Id "/subscriptions/437b2bfa-850e-4464-b6c2-38a68cda7c69/resourceGroups/rg-infra-templates-prd-002/providers/Microsoft.Compute/images/vm-rhel74template-prd-002"} "npd01" {$vmConfig | Set-AzureRmVMSourceImage -Id "/subscriptions/76297098-764c-43de-8525-c9fda1b237be/resourceGroups/rg-infra-templates-tst-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-103"} "infra01" {$vmConfig | Set-AzureRmVMSourceImage -Id "/subscriptions/e53aa0c7-824d-40a2-b420-4ab77b1051d2/resourceGroups/rg-infra-templates-prd-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-403"} "prd01" {$vmConfig | Set-AzureRmVMSourceImage -Id "/subscriptions/437b2bfa-850e-4464-b6c2-38a68cda7c69/resourceGroups/rg-infra-templates-prd-002/providers/Microsoft.Compute/images/vm-rhel74template-prd-003"} } } $vmConfig | Add-AzureRmVMNetworkInterface -Id $VMNIC.ID $vmConfig | Set-AzureRmVMBootDiagnostics -Enable -ResourceGroupName $ResourceGroup -StorageAccountName $VMDiagStorageAcct Write-Verbose "Creating VM" New-AzureRMVM -VM $vmConfig -ResourceGroupName $resourceGroup -Location $VMLocation -DisableBginfoExtension -AsJob } End { } } function Remove-ITDAzureRMResourceGroupTags { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Input File [Parameter(Mandatory=$true)] [String] $InputFile, # Azure Tag to Remove [Parameter(Mandatory=$true)] [string] $RemoveTag ) Begin { } Process { If($InputFile) { $filetable = Import-CSV -Path $InputFile foreach($record in $filetable) { $ResTag = $record.ResourceGroup $SubTag = $record.Subscription Set-AzureRmContext $SubTag $GroupTags = (Get-AzureRmResourceGroup -Name $ResTag).Tags $GroupTags.Remove($RemoveTag) Set-AzureRmResourceGroup -Name $ResTag -Tag $GroupTags $Resources = Get-AzureRmResource | Where-Object {$_.ResourceGroupName -eq $ResTag} ForEach ($Resource in $Resources) { $ResourceTags = $Resource.Tags $GroupTags.Remove($RemoveTag) Set-AzureRMResource -ResourceID $Resource.ResourceID -Tag $ResourceTags -Confirm:$false -Force } } Return } } End { } } <# .Synopsis Create new Azure data disk, and attach to the specified VM .DESCRIPTION Create new Azure data disk, and attach to the specified VM. - Determines ResourceGroup where disk will be created, the name of the disk, and the LUN ID the disk will use. - SizeGB must be unique for each disk attached to a virtual machine. If the SizeGB parameter is not unique, new size will be automatically determined. .EXAMPLE Add-ITDAzureRMNewDataDisk -VMName vm-itdvm-tst -SizeGB 32 #> function Add-ITDAzureRMNewDataDisk { [CmdletBinding()] Param ( [string] $VMName, [int[]] $SizeGB ) Begin { $search=@() $Hostname=$VMName.split('-')[1] $Environment=$VMName.split('-')[2] Get-AzureRmSubscription | ForEach-Object{ $Subscription=$_ Set-AzureRmContext $_ | Out-Null $search += Get-AzureRmVM | Where-Object Name -eq $VMName | select *,@{n='SubscriptionName';e={$Subscription.Name}} } } Process { If($search.count -eq 1) { Set-AzureRmContext $search.SubscriptionName $ResourceGroup = $search.ResourceGroupName.ToLower() $Location = (Get-AzureRmResourceGroup -Name $ResourceGroup).Location $VM = Get-AzureRmVM -Name $VMName -ResourceGroupName $ResourceGroup $Zone=$VM.Zones ForEach($Size in $SizeGB) { $ExistingDisks = @($VM.StorageProfile.DataDisks | select *,@{n='ItdId';e={[int]($_.Name -replace "vm-$hostname-app-$environment-")}}) $NewDiskItdIdInt = ($ExistingDisks | Sort-Object ItdId -Descending | select -First 1).ItdId + 1 $NewDiskItdIdStr = $NewDiskItdIdInt.ToString("000") $NewDiskName="vm-$Hostname-app-$Environment-$NewDiskItdIdStr" #vm-itduc4p1-app-tst-001 $LunID = ($ExistingDisks | Sort-Object Lun -Descending | Select-Object -First 1).Lun + 1 $count=0 If($ExistingDisks) { while ($Size -match $ExistingDisks.DiskSizeGB) { $count++ Write-Warning "SizeGB: $Size, Count: $count" If($count -ge 11) { Write-Error "Disk size not available" -ErrorAction Stop } Else { $Size = $Size - 1 } } } Write-Warning "SizeGB: $Size, Count: $count" $AzureRmDiskConfigParams=@{ DiskSizeGB = $Size Location = $Location CreateOption = "Empty" SkuName = "Premium_LRS" } If($Zone) { Write-Verbose "VM is located in Zone $Zone" $AzureRmDiskConfigParams += @{Zone = $Zone} } #$DiskConfig = New-AzureRmDiskConfig -DiskSizeGB $Size -Location $Location -CreateOption Empty -SkuName Premium_LRS $DiskConfig = New-AzureRmDiskConfig @AzureRmDiskConfigParams If(!(Get-AzureRmDisk -ResourceGroupName $ResourceGroup -DiskName $NewDiskName -ErrorAction SilentlyContinue)) { $NewDisk = New-AzureRmDisk -DiskName $NewDiskName -Disk $DiskConfig -ResourceGroupName $ResourceGroup $VM = Add-AzureRmVMDataDisk -Name $NewDiskName -CreateOption Attach -ManagedDiskId $NewDisk.Id -VM $VM -Lun $LunID -Caching ReadOnly Update-AzureRmVM -VM $VM -ResourceGroupName $ResourceGroup -AsJob } } } Else { Write-Error "Search count invalid" -ErrorAction SilentlyContinue } } End { } } <# .SYNOPSIS Provision Windows or RHEL VM .DESCRIPTION Create Azure IaaS VM, to ITD standards: *** Requires resource group to be created before running *** Required DNS record for FQDN. - Create Storage Account for Resource Group if missing - Create VM - Scaled to hardware specifications, B-class for tst, D-class for prd -Size parameter exists if above restrictions must be overridden - NIC created, IP pulled from DNS - Auto decide VLAN/subnet based on Environment parameter - Operating system chosen by user - Auto generate PasswordState record (ITDActiveDirectory module required) with GeneratePassword parameter - Utilize VMCredential parameter to set local administrator (itdadmin) password .EXAMPLE New-ITDAzureVM -ComputerName itddc20.nd.gov -CPU 2 -Memory 8 -AppName "Infra-Active Directory" -Environment "prd" -OperatingSystem WS2012R2 -GeneratePassword .EXAMPLE New-ITDAzureVM -ComputerName itddc21.nd.gov -CPU 2 -Memory 8 -AppName "Infra-Active Directory" -Environment "prd" -OperatingSystem WS2012R2 -VMCredential (Get-Credential) #> function New-ITDAzureVM { [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [string] $ComputerName, [Parameter(Mandatory=$true)] [int] $CPU, [Parameter(Mandatory=$true)] [int] $Memory, [Parameter(Mandatory=$true)] [string] $AppName, [Parameter(Mandatory=$true)] [ValidateSet("tst","prd")] [string] $Environment, [string] $ResourceGroupIndex, [Parameter(Mandatory=$true)] [ValidateSet("WS2012R2","WS2016","WS2019","WS2022","W10v1803","W10v1809","RHEL7.4")] [string] $OperatingSystem, [ValidateSet(1,2,3)] [int] $AvailZone, [Parameter(ParameterSetName="PasswordGenerate")] [switch] $GeneratePassword, [Parameter(ParameterSetName="PasswordEnter")] [PSCredential] $VMCredential #[string] #$VMSizeOverride, #[ValidateSet('infra01','npd01','prd01')] #[string] #$SubscriptionOverride ) begin { $location="centralus" $username = "itdadmin" $VMOwner = $AppName.split('-')[0].ToLower() $VMFunction = (($AppName -replace "$VMOwner-") -replace "-").ToLower() -replace " " $Name=$ComputerName.Split('.')[0] $IPAddress = (Resolve-DnsName -Name $ComputerName -ErrorAction Stop).IpAddress $ResourceGroup = "rg-$VMOwner-$VMFunction-$Environment" If($ResourceGroupIndex){$ResourceGroup = $ResourceGroup + "-$ResourceGroupIndex"} $VMName = "vm-$Name-$Environment" } process { switch ($Environment) { tst { $VMSizeFilter="*_B*s*" $Subscription = "npd01" $VNet="vnet-npd01-001" $VNetSubnet="sn-shared-zerotrust-npd-10.21.8.0_22" } prd { $VMSizeFilter="*_D*s*" $Subscription = "prd01" $VNet="vnet-prd01-001" $VnetSubnet="sn-shared-zerotrust-prd-10.21.12.0_22" } Default { Write-Error "Environment failed" -ErrorAction Stop } } switch ($OperatingSystem) { 'WS2012R2' { $VMOS = "Windows" $Publisher = "MicrosoftWindowsServer" $Offer = "WindowsServer" $sku = "2012-R2-Datacenter" $PSList = "CSRC" } 'WS2016' { $VMOS = "Windows" $Publisher = "MicrosoftWindowsServer" $Offer = "WindowsServer" $sku = "2016-Datacenter" $PSList = "CSRC" } 'WS2019' { $VMOS = "Windows" $Publisher = "MicrosoftWindowsServer" $Offer = "WindowsServer" $sku = "2019-Datacenter" $PSList = "CSRC" } 'WS2022' { $VMOS = "Windows" $Publisher = "MicrosoftWindowsServer" $Offer = "WindowsServer" $sku = "2022-Datacenter" $PSList = "CSRC" } 'W10v1803' { $VMOS = "Windows" $Publisher = "MicrosoftWindowsDesktop" $Offer = "Windows-10" $sku = "rs4-pro" $PSList = "CSRC" } 'W10v1809' { Write-Error "W10v1809 not available" -ErrorAction Stop $VMOS = "Windows" $Publisher = "MicrosoftWindowsDesktop" $Offer = "Windows-10" $sku = "rs5-pro" $PSList = "CSRC" } 'RHEL7.4' { $VMOS = "Linux" $Publisher = $null $Offer = $null $sku = $null $PSList = "Linux" } } If ($GeneratePassword) { Write-Verbose "GeneratePassword true" try { $TimeStamp = Get-Date -UFormat "%Y%m%d-%H%M%S" Write-Warning "[$ComputerName]:$TimeStamp - Password generation " #$password = ConvertTo-SecureString (New-ITDLocalAdminPasswordstateRecord -ComputerName $ComputerName -Azure -PasswordstateList $PSList -Credential $AdminCred).Password -AsPlainText -Force $password = ConvertTo-SecureString (New-ITDPasswordstateRecord -Title $ComputerName -Description "Local Admin" -PSList $PSList -GeneratePassword -Username itdadmin -ReturnPassword).Password -AsPlainText -Force } catch { Write-Error "GeneratePassword failed, process manually" -ErrorAction Stop } } Else { Write-Verbose "GeneratePassword false" $password = $VMCredential.Password } $VMCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$password $VMSize = Get-AzureRmVMSize -Location $location | ` Where-Object Name -Like "$VMSizeFilter" | ` Where-Object {$_.NumberOfCores -ge $CPU -and $_.MemoryInMB -ge ($Memory * 1024)*0.5 } | ` Where-Object Name -NotMatch "_Promo" | ` Sort-Object NumberOfCores,MemoryInMB | ` Select-Object -First 1 If($SubscriptionOverride) { $Subscription = $SubscriptionOverride } If($VMSizeOverride) { $VMSize = Get-AzureRmVMSize -Location $location | ` Where-Object Name -Like $VMSizeOverride } $NewITDAzureRMVMParams=@{ VMFQDN = $ComputerName VMSubscription = $Subscription VMEnvironment = $Environment VMOwner = $VMOwner VMFunction = $VMFunction VMSize = $VMSize.Name VMOS = $VMOS VMPublisher = $Publisher VMOffer = $Offer VMSku = $sku VMVnetName = $VNet VMSubnet = $VNetSubnet VMLocation = $location VMIP = $IPAddress VMCredential = $VMCredential } If($AvailZone){$NewITDAzureRMVMParams += @{VMAvailZone = $AvailZone}} If($ResourceGroupIndex){$NewITDAzureRMVMParams += @{$ResourceGroupIndexNumber = $ResourceGroupIndex}} <# Write-Warning $NewITDAzureRMVMParams.VMFQDN Write-Warning $NewITDAzureRMVMParams.VMSubscription Write-Warning $NewITDAzureRMVMParams.VMEnvironment Write-Warning $NewITDAzureRMVMParams.VMOwner Write-Warning $NewITDAzureRMVMParams.VMFunction Write-Warning $NewITDAzureRMVMParams.VMSize Write-Warning $NewITDAzureRMVMParams.VMOS Write-Warning $NewITDAzureRMVMParams.VMPublisher Write-Warning $NewITDAzureRMVMParams.VMOffer Write-Warning $NewITDAzureRMVMParams.VMSku Write-Warning $NewITDAzureRMVMParams.VMVnetName Write-Warning $NewITDAzureRMVMParams.VMSubnet Write-Warning $NewITDAzureRMVMParams.VMLocation Write-Warning $NewITDAzureRMVMParams.VMIP Write-Warning $NewITDAzureRMVMParams.VMCredential Write-Warning $NewITDAzureRMVMParams.VMAvailZone #> New-ITDAzureRMVM @NewITDAzureRMVMParams <# New-ITDAzureRMVM -VMFQDN $ComputerName ` -VMSubscription $Subscription ` -VMEnvironment $Environment ` -VMOwner $VMOwner ` -VMFunction $VMFunction ` -VMSize $VMSize.Name ` -VMOS $VMOS ` -VMPublisher $Publisher ` -VMOffer $Offer ` -VMSku $Sku ` -VMVNetName $VNet ` -VMSubnet $VNetSubnet ` -VMLocation $location ` -VMIP $IPAddress ` -VMCredential $VMCredential ` -Verbose #> # wait for provisioning completion do { Start-Sleep -Seconds 15 } while ( (Get-AzureRmVM -ResourceGroupName $ResourceGroup | Where-Object Name -Match $Name).ProvisioningState -eq "Creating") # check NIC $nic=Get-AzureRmNetworkInterface -ResourceGroupName $ResourceGroup | Where-Object Name -Match $Name $nic.IpConfigurations[0].PrivateIpAllocationMethod = "Static" $nic.IpConfigurations[0].PrivateIpAddress = $IPAddress Set-AzureRmNetworkInterface -NetworkInterface $nic #customize switch ($VMOS) { 'Windows' { Invoke-AzureRmVMRunCommand -VMName $VMName ` -ResourceGroupName $ResourceGroup ` -CommandId 'RunPowerShellScript' ` -ScriptPath "S:\Distributed Systems\Systems\Azure\Scripts\WindowsCustomization.ps1" ` -AsJob } 'Linux' { } Default { } } } end { } } <# .SYNOPSIS Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet .INPUTS Inputs to this cmdlet (if any) .OUTPUTS Output from this cmdlet (if any) .NOTES General notes .COMPONENT The component this cmdlet belongs to .ROLE The role this cmdlet belongs to .FUNCTIONALITY The functionality that best describes this cmdlet #> function New-ITDAzureRMResourceGroup { [CmdletBinding()] Param ( [string[]] $AppName, [ValidateSet('prd','tst','infra')] [string[]] $Environment, [ValidateSet('centralus')] [string] $Location, [ValidateSet('VM','Network')] [string] $Ownership ) begin { $Subscriptions=Get-AzureRmSubscription } process { ForEach($App in $AppName) { ForEach($Env in $Environment) { $VMOwner = $App.split('-')[0].ToLower() $VMFunction = (($App -replace "$VMOwner-") -replace "-").ToLower() -replace " " $ResourceGroupName = "rg-$VMOwner-$VMFunction-$Env" Write-Verbose "Resource Group Name: $ResourceGroupName" $Tags = @{ "ApplicationName" = $AppName; "Environment" = $Environment; } switch ($Env) { 'infra' { $SubscriptionsToUse=@("infra01","infradr01") } 'prd' { $SubscriptionsToUse=@("prd01","prddr01") } 'tst' { $SubscriptionsToUse=@("tst01","tstdr01") } Default { Write-Error "invalid Environment" -ErrorAction Stop } } ForEach($Sub in $SubscriptionsToUse) { Set-AzureRmContext -Context ($Subscriptions | Where-Object Name -eq $Sub) Write-Verbose "Creating Resource Group $ResourceGroupName" New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location -Tag $Tags Write-Verbose "Setting $Ownership Permissions on Resource Group $ResourceGroupName" Set-ITDAzureRMResourceGroupAssignment -Ownership $Ownership -ResourceGroup $ResourceGroupName } } } } end { } } <# .SYNOPSIS Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet .INPUTS Inputs to this cmdlet (if any) .OUTPUTS Output from this cmdlet (if any) .NOTES General notes .COMPONENT The component this cmdlet belongs to .ROLE The role this cmdlet belongs to .FUNCTIONALITY The functionality that best describes this cmdlet #> function Find-ITDAzureRMVM { [CmdletBinding()] Param ( [string] $VMName ) begin { } process { $search=@() $Hostname=$VMName.split('-')[1] $Environment=$VMName.split('-')[2] Get-AzureRmSubscription | ForEach-Object{ $Subscription=$_ Set-AzureRmContext $_ | Out-Null $search += Get-AzureRmVM | Where-Object Name -eq $VMName | select *,@{n='SubscriptionName';e={$Subscription.Name}} } If(@($search).count -eq 1) { Write-Output $search } else { $count = $search.count Write-Error ($count + "VMs found") } } end { } } <# .SYNOPSIS Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet .INPUTS Inputs to this cmdlet (if any) .OUTPUTS Output from this cmdlet (if any) .NOTES General notes .COMPONENT The component this cmdlet belongs to .ROLE The role this cmdlet belongs to .FUNCTIONALITY The functionality that best describes this cmdlet #> function Set-ITDAzureRmVMBackup { [CmdletBinding()] Param ( [string[]] $VMName ) begin { } process { ForEach($name in $VMName) { $Vault = $null $BackupPolicy = $null $vm = Find-ITDAzureRMVM -VMName $name -ErrorAction Stop Set-AzureRmContext $vm.SubscriptionName $Vault = Get-AzureRmRecoveryServicesVault -Name rs-infra-azbackup-prd-100 Set-AzureRmRecoveryServicesVaultContext -Vault $Vault $BackupPolicy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "DefaultPolicy" Enable-AzureRmRecoveryServicesBackupProtection -Policy $BackupPolicy -Name $$vm.Name -ResourceGroupName $vm.ResourceGroupName } } end { } } function New-ITDAzureRMResourceGroupAll { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Subscription for the Resource Group [Parameter(Mandatory=$true)] [String] $Subscription, # Resource Group Name [Parameter(Mandatory=$true)] [string] $Name, # Ownership -- VM or Network [Parameter(Mandatory=$true)] [String] $Ownership, # Azure Region [Parameter(Mandatory=$true)] [string] $Location, # Application Name [Parameter(Mandatory=$true)] [string] $ApplicationName ) Begin { Set-AzureRmContext $Subscription $TagHashTable = @{} $ApplicationNameKey = "ApplicationName" $TagHashTable.Add($ApplicationNameKey, $ApplicationName) } Process { New-AzureRmResourceGroup -Name $Name -Location $Location -Tag $TagHashTable Set-ITDAzureRMResourceGroupAssignment -Ownership $Ownership -ResourceGroup $Name } End { } }