# https://96bdfe01-af80-4575-8f23-e7057184c8f6.webhook.cus.azure-automation.net/webhooks?token=dVIj9zHSJwNeR2Ow8QTOoiSoKaPPux9EVJsQAMiGUPg%3d
<#
$ComputerName = 'itddotfrsql3.nd.gov'
$CPU = 8
$MemoryGB = 32
$OS = 'Windows Server 2019 Datacenter'
$Subnet = '10.21.12.0/22'
$Environment = "Production"
$Platform = "Azure"
$AppName = 'DOT-FacialRec'
$LicensingRestrictions='Microsoft SQL Enterprise'
$Credential = $PrvCred
#>
[CmdletBinding()]
param
(
    [Parameter(Mandatory = $false)]
    [object] $WebhookData
)

<# New-ITDVMwareWindowsVMAA
#>

function New-ITDAzureWindowsVMAA {
    [CmdLetBinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [string]
        $ComputerName,

        [Parameter(Mandatory = $true)]
        [int]
        $CPU,

        [Parameter(Mandatory = $true)]
        [int]
        $MemoryGB,

        #[Parameter(Mandatory = $true)]
        #[int]
        #$DiskOS,

        #[Parameter(Mandatory = $true)]
        #[int]
        #$DiskData,

        [Parameter(Mandatory = $true)]
        [string]
        $Subnet,

        [Parameter(Mandatory = $true)]
        [string]
        $OS,

        [Parameter(Mandatory = $true)]
        [string]
        $Environment,

        [Parameter(Mandatory = $true)]
        [string]
        $AppName,

        [Parameter(Mandatory = $true)]
        [string]
        $LicensingRestrictions

        #[Parameter(Mandatory = $true)]
        #[PSCredential]
        #$Credential
    )

    
    $Body = "
    ComputerName=$ComputerName
    CPU=$CPU
    MemoryGB=$MemoryGB
    VlanId=$VlanId
    OS=$OS
    Environment=$Environment
    Datacenter=$Datacenter
    LicensingRestrictions=$LicensingRestrictions
    AppName=$AppName

    RunningOn=$env:computername
    RunningAs=$env:username
    Credential=$Credential.UserName
    "
    Send-MailMessage -From "zmauto@nd.gov" -To "zmeier@nd.gov" -SmtpServer apprelay1.nd.gov -Body $Body -Subject "AutoBuildAzure-$ComputerName"

    $FQDN = $ComputerName
    $tenantId = '2dea0464-da51-4a88-bae2-b3db94bc0c54'

    If ($Credential) {
        $IaasAuto = $Credential
    }

    #$IaasAutoAzApp = Get-AutomationPSCredential -Name 'Azure IaaS Service Principal'

    Write-Warning "[$FQDN]:Start"
    $SPCred = $IaasAuto
    $ADCred = $IaasAuto
    $PSCred = $IaasAuto
    $VMCred = $IaasAuto
    $CcmCred = $IaasAuto

    #$RadiusCred = $RadiusCred
    $RadiusCred = New-Object System.Management.Automation.PSCredential($IaasAuto.username.split('\')[1], ($IaaSAuto.Password))

    Clear-DnsClientCache
    $HostName = $FQDN.split('.')[0]

    

    # Infoblox
    #$InfobloxVlanMetadata = Get-ITDIbVlan -CIDR $Subnet -Credential $RadiusCred   # not valid for Azure
    #$Cidr = ($InfobloxVlanMetadata.AssignedTo | Out-String).TrimEnd()
    $Cidr = $Subnet
    [Net.IpAddress]$NetworkId = $Cidr.split('/')[0]
    [Net.IPAddress]$IpAddress = (Resolve-DnsName -Name $FQDN -ErrorAction SilentlyContinue).IPAddress
    $SubnetMaskInt = $CIDR.split('/')[1]
    $Int64 = ([convert]::ToInt64(('1' * $SubnetMaskInt + '0' * (32 - $SubnetMaskInt)), 2))
    [Net.IPAddress]$SubnetMask = '{0}.{1}.{2}.{3}' -f ([math]::Truncate($Int64 / 16777216)).ToString(),
        ([math]::Truncate(($Int64 % 16777216) / 65536)).ToString(),
        ([math]::Truncate(($Int64 % 65536) / 256)).ToString(),
        ([math]::Truncate($Int64 % 256)).ToString()
    $IPSplit = $Subnet.Split('.')
    [Net.IPAddress]$DefaultGateway = ($IPSplit[0] + '.' + $IPSplit[1] + '.' + $IPSplit[2] + '.' + (($CIDR.split('/')[0].split('.')[-1] -as [int]) + 1) )

    If ($IpAddress) {
        If (($IpAddress.Address -band $SubnetMask.Address) -eq ($NetworkId.Address -band $SubnetMask.Address)) {
            Write-Warning "DNS record already exists, CIDR Block match"
        }
        Else {
            Write-Error "DNS record already exists, and does not match CIDR Block"
            Break
        }
    }
    Else {
        New-ITDIbDNSRecordNextAvailableIP -Hostname $FQDN -CIDR $CIDR -Credential $RadiusCred
        Start-Sleep -Seconds 5
        [Net.IPAddress]$IpAddress = (Resolve-DnsName -Name $FQDN -ErrorAction SilentlyContinue).IPAddress
    

        If ((Test-NetConnection -ComputerName $IpAddress.IPAddressToString).PingSucceeded) {
            Write-Error "IP Address already in use." -ErrorAction Stop
        }
    }


    # Passwordstate
    If ($FQDN -like "itdcnd*") {
        $PasswordStateList = "Peoplesoft Share PW"
    }
    Else {
        $PasswordStateList = "CSRC"
    }

    $LocalCredential = New-ITDPassword -Title $FQDN -UserName itdadmin -Description 'Local Administrator' -PasswordList $PasswordStateList -Credential $PSCred
    #$GuestCredentialBB = New-Object System.Management.Automation.PSCredential ('Administrator', ($LocalCredential.Password | ConvertTo-SecureString -AsPlainText -Force))
    #$GuestCredentialAB = New-Object System.Management.Automation.PSCredential ($LocalCredential.UserName, ($LocalCredential.Password | ConvertTo-SecureString -AsPlainText -Force))
    $GuestCredentialAB = New-Object System.Management.Automation.PSCredential ('itdadmin', ($LocalCredential.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force))
    $GuestCredentialBB = New-Object System.Management.Automation.PSCredential ('Administrator', ($LocalCredential.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force))
    #$GuestCredential = $GuestCredentialBB

    switch ($Environment) {
        { $_ -eq 'Test' -or $_ -eq 'Development' } {
            Write-Warning 'Environment is Test or Development'
            $EnvShortString = 'tst'
            #$VMSizeFilter="*_B*s*"
            $VMSizeFilter1 = "*_D[0-9]*s_v3"
            $VMSizeFilter2 = "*_E[0-9]*s_v3"
            $VMSizeFilter3 = "*_F[0-9]*s_v2"
            
            $Subscription = "npd01"
            $VNet = "vnet-npd01-001"
            $VNetSubnet = "sn-shared-zerotrust-npd-10.21.8.0_22"
        }
        'Production' {
            Write-Warning 'Environment is Production'
            $EnvShortString = 'prd'
            #$VMSizeFilter="*_D*s_*"
            $VMSizeFilter1 = "*_D[0-9]*s_v3"
            $VMSizeFilter2 = "*_E[0-9]*s_v3"
            $VMSizeFilter3 = "*_F[0-9]*s_v2"
            $Subscription = "prd01"
            $VNet = "vnet-prd01-001"
            $VnetSubnet = "sn-shared-zerotrust-prd-10.21.12.0_22"
        }
        'CARES-tst' {
            Write-Warning 'Environment is CARES-tst'
            $EnvShortString = 'tst'
            #$VMSizeFilter="*_D*s_*"
            $VMSizeFilter1 = "*_D[0-9]*s_v3"
            $VMSizeFilter2 = "*_E[0-9]*s_v3"
            $VMSizeFilter3 = "*_F[0-9]*s_v2"
            $Subscription = "cares01"
            $VNet = "vnet-infra-azurenetworking-cares01-npd"
            $VnetSubnet = "sn-shared-zerotrust-npd-10.69.254.0_24"
        }
        'CARES-prd' {
            Write-Warning 'Environment is CARES-prd'
            $EnvShortString = 'prd'
            #$VMSizeFilter="*_D*s_*"
            $VMSizeFilter1 = "*_D[0-9]*s_v3"
            $VMSizeFilter2 = "*_E[0-9]*s_v3"
            $VMSizeFilter3 = "*_F[0-9]*s_v2"
            $Subscription = "cares01"
            $VNet = "vnet-infra-azurenetworking-cares01-prd"
            $VnetSubnet = "sn-shared-zerotrust-prd-10.69.126.0_24"
        }
        
        Default {
            Write-Error "Environment failed" -ErrorAction Stop
        }
    }

    switch ($OS) {
        "Windows Server 2019 Datacenter" {
            $VMOS = "Windows"
            $Publisher = "MicrosoftWindowsServer"
            $Offer = "WindowsServer"
            $sku = "2019-Datacenter"
        }
        "Windows Server 2022 Datacenter" {
            $VMOS = "Windows"
            $Publisher = "MicrosoftWindowsServer"
            $Offer = "WindowsServer"
            $sku = "2022-datacenter"
        }
        Default { Write-Error "Invalid operating system" -ErrorAction Stop }
    }

    # finalize VM size
    Connect-AzAccount -ServicePrincipal -Credential $IaasAutoAzApp -Tenant $tenantId

    $location = "centralus"
    $VMSize = Get-AzVMSize -Location $location | `
        Where-Object { $_.Name -Like "$VMSizeFilter1" -or $_.Name -Like "$VMSizeFilter2" -or $_.Name -Like "$VMSizeFilter3" } | `
        Where-Object { $_.NumberOfCores -ge $CPU -and $_.MemoryInMB -ge ($Memory * 1024) } | `
        Where-Object Name -NotMatch "_Promo" | `
        Sort-Object NumberOfCores, MemoryInMB | `
        Select-Object -First 1

        
    # resource group things
    $VMOwner = $AppName.split('-')[0].ToLower()
    $VMFunction = (($AppName -replace "$VMOwner-") -replace "-").ToLower() -replace " "
    #$IPAddress = (Resolve-DnsName -Name $ComputerName -ErrorAction Stop).IpAddress
    $ResourceGroup = "rg-$VMOwner-$VMFunction-$EnvShortString"
    If ($ResourceGroupIndex) { $ResourceGroup = $ResourceGroup + "-$ResourceGroupIndex" }
    $VMName = "vm-$HostName-$EnvShortString"


    $NewITDAzureRMVMParams = @{
        VMFQDN         = $ComputerName
        VMSubscription = $Subscription
        VMEnvironment  = $EnvShortString
        VMOwner        = $VMOwner
        VMFunction     = $VMFunction
        VMSize         = $VMSize.Name
        VMOS           = $VMOS
        VMPublisher    = $Publisher
        VMOffer        = $Offer
        VMSku          = $sku
        VMVnetName     = $VNet
        VMSubnet       = $VNetSubnet
        VMLocation     = $location
        VMIP           = $IPAddress.IPAddressToString
        VMCredential   = $LocalCredential
        AppName        = $AppName
    }
    <#
        $VMFQDN = $ComputerName
        $VMSubscription = $Subscription
        $VMEnvironment = $EnvShortString
        $VMOwner = $VMOwner
        $VMFunction = $VMFunction
        $VMSize = $VMSize.Name
        $VMOS = $VMOS
        $VMPublisher = $Publisher
        $VMOffer = $Offer
        $VMSku = $sku
        $VMVnetName = $VNet
        $VMSubnet = $VNetSubnet
        $VMLocation = $location
        $VMIP = $IPAddress
        $VMCredential = $LocalCredential
        $AppName = $AppName
#>
    New-ITDAzureRMVM @NewITDAzureRMVMParams

    # wait for build
    $VMName = ('vm-' + $ComputerName.split('.')[0] + '-' + $EnvShortString)

    $VMStatus = $null
    $VMCreation = $Null
    While ($VMCreation -ne "Complete") {
        If (( (Get-AzVM -ResourceGroupName $ResourceGroup -Name $VMName -Status).Statuses | Where-Object Code -Match "PowerState").Code -eq "PowerState/running") {
            $VMCreation = "Complete"
        }
        else {
            Start-Sleep -Seconds 300
        }
    }
    
    Start-Sleep -Seconds 30
    
    # Add extra disk
    Add-ITDAzureRMNewDataDisk -VMName $VMName -SizeGB 20

    # pre-firewall Guest OS customization
    Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\1-SetWMITags.ps1'
    Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\3-Disks.ps1'
    Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\5-TimeZone.ps1'
    Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\6-PerformanceCounters.ps1'
    Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\7-DisableWindowsFirewall.ps1'
    
    # determine Active Directory Forest and OU
    $DomainName = $FQDN.Substring($FQDN.IndexOf(".") + 1)
    switch ($DomainName) {
        'nd.gov' {
            $SearchBaseDomain = "dc=nd,dc=gov"
        }
        'ndcloud.gov' {
            $SearchBaseDomain = "dc=ndcloud,dc=gov"
        }
    }
    If ($DomainName -eq "nd.gov") {
        $OUAppName = Get-ADOrganizationalUnit -Server $DomainName -SearchBase ("OU=Windows,OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq $AppName }
        If (!($OUAppName)) {
            $OUAppName = Get-ADOrganizationalUnit -SearchBase ("OU=Windows,OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq 'All-General' }
        }
        $ExistingADComputer = Get-ADComputer -Filter { Name -eq $Hostname }
        If ($ExistingADComputer) {
            If ($ExistingADComputer.DistinguishedName -like ("*" + $AppName + "*") -or $ExistingADComputer.DistinguishedName -like "*All-General*") {
                Write-Warning "AD object already exists, OU path does match"
                $OuFinal = $ExistingADComputer.DistinguishedName -replace '^.+?(?<!\\),', ''
            }
            Else {
                Write-Error "AD object already exists, OU path mismatch"
                Exit
                Exit
            }
        }
        Else {
            switch ($Environment) {
                'Test' {
                    If ($AppName -like "Shared-Peoplesoft*") { $EnvString = "Non-Prod" }
                    Else { $EnvString = "Test" }
                    $OuAppNameEnv = Get-ADOrganizationalUnit -SearchBase $OUAppName.DistinguishedName -Filter * | Where-Object Name -EQ "$EnvString"
                }
                'Production' {
                    If ($AppName -like "Shared-Peoplesoft*") { $EnvString = "Prod" }
                    Else { $EnvString = "Prod" }
                    
                    $OuAppNameEnv = Get-ADOrganizationalUnit -SearchBase $OUAppName.DistinguishedName -Filter * | Where-Object Name -EQ "$EnvString"
                }
            }
            If ($OuAppNameEnv) { $OUFinal = $OUAppNameEnv.DistinguishedName }
            Else { $OuFinal = $OUAppName.DistinguishedName }

            New-ADComputer -Name $HostName.ToUpper() -Path $OUFinal -Credential $ADCred -Description ($SPItem | Select-Object AppName, Environment | ConvertTo-Json)
        }
    }

    # disconnect, wait for firewall, then reconnect
    Disconnect-AzAccount
    While ($PingStatus -eq $false) {
        $PingTest = Test-NetConnection -ComputerName $FQDN
        If ($PingTest.PingSuccedded -eq $true) {
            $PingStatus = $true
        }
        Start-Sleep -Seconds 300
    }

    
    Connect-AzAccount -ServicePrincipal -Credential $IaasAutoAzApp -Tenant $tenantId
    Set-AzContext -Subscription $Subscription
    


    # post-firewall Guest OS customization
    switch ($DomainName) {
        'nd.gov' {
            Write-Warning "Attempting domain join nd.gov"
            Write-Warning "Domain: $DomainName"
            Write-Warning "OuPath: $OuFinal"
            Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\8-Domain-ndgov.ps1' -Parameter @{"DomainName" = 'nd.gov'; "OuPath" = ' CN=ITDSOSCMTSQL22,OU=SOS-BLS,OU=SOS-All,OU=Windows,OU=SERVERS,OU=COMPUTERS,OU=ITD,DC=nd,DC=gov' }
        }
    }



    Write-Verbose -Message "Activating windows against $KMS..."
    Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\9-KMS.ps1'

    <#
    Write-Warning "[$FQDN]:Register SCCM Client"
    $CcmRegistered = $false
    While ($CcmRegistered -eq $false) {
        $CcmResult = Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroup -Name $VMName -CommandId 'RunPowerShellScript' -ScriptPath 'C:\AzWinBuild\10-SCCM-a.ps1'
        If ($CcmResult.Value -match "SCCM Client is registered") {
            Write-Warning "Client is registered."
            $CcmRegistered = $true
        }
        ElseIf ($CcmRegistered -eq $false) { Start-Sleep -Seconds 60 }
    }

    Write-Warning -Message "[$FQDN]:Approve SCCM Client"
    #Start-Sleep -Seconds 30   # ADD LOOP/SMARTS TO WAIT FOR DISCOVERY AND ANOTHER FOR APPROVAL
    Invoke-Command -ComputerName itdsccmp2.nd.gov -Credential $CcmCred -ArgumentList $Hostname -ScriptBlock {
        Import-Module 'D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
        $PSDrives = Get-PSDrive
        If ($PSDrives | Where-Object Name -EQ "ITD") {
            # ITD Drive exists, do nothing
        }
        else {
            New-PSDrive -Name "ITD" -PSProvider AdminUI.PS.Provider\CMSite -Root itdsccmp2.nd.gov   
        }

        Set-Location ITD:\
        $Device = Get-CMDevice -Name $args[0]
        If ($Device.IsApproved -eq 0) {
            Approve-CMDevice -DeviceName $args[0]
        }
    }
    #>


}

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,

        # App name to be used for the RG
        [Parameter(Mandatory = $true)]
        [string]
        $AppName
    )
    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"}
        #removing diag storage account because replaced by managed storage accounts for boot diagnostics
        #$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"
        }
        #>

        <#
        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-AzContext $VMSubscription
        $ResGroupExist = ""
        Write-Verbose "Creating Resource Group if it doesn't exist"      
        $ResGroupExist = Get-AzResourceGroup -Name $ResourceGroup -ErrorAction SilentlyContinue

    
        If (@($ResGroupExist).count -gt 1) {
            Write-Error "Multiple Resource Groups matched" -ErrorAction Stop
        }
        If (@($ResGroupExist).count -lt 1) {
            Write-Warning "No matching resource group found, creating it now"
            New-AzResourceGroup -Name $ResourceGroup -Location $VMLocation -Tag @{ApplicationName = $AppName }
            $ResourceGroupName = $ResourceGroupSearch.ResourceGroupName
            #Write-Error "No Resource Groups matched" -ErrorAction Stop
        }
        If (@($ResGroupExist).count -eq 1) {
            Write-Warning "Exactly one matching resource group found"
            $ResourceGroupName = $ResourceGroupSearch.ResourceGroupName
        }
        
        <#
        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-AzAvailabilitySet -ResourceGroupName $ResourceGroup -Name $VMASName -ErrorAction SilentlyContinue
            If($VMASExisting)
            {
                $VMASID = $VMASExist.id    
            }
            Else
            {
                New-AzAvailabilitySet -ResourceGroupName $ResourceGroup -Name $VMASName -Location $VMLocation -PlatformFaultDomainCount 3 -PlatformUpdateDomainCount 5 -Sku Aligned
                $VMASID = (Get-AzAvailabilitySet -ResourceGroupName $ResourceGroup -Name $VMASName).id
            }
        }
#>

        Write-Verbose "Preparing Network Config"
        $VNet = (Get-AzVirtualNetwork | 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-AzNetworkInterfaceIpConfig -Name $VMIPConfigName -PrivateIpAddress $VMIP -PrivateIpAddressVersion IPv4 -Subnet $Subnet
        $VMNIC = New-AzNetworkInterface -IpConfigurationName $IPConfig -Location $VMLocation -Name $VMNICName -ResourceGroupName $ResourceGroup -SubnetId $SubnetID
        $VMNIC.IpConfigurations[0].PrivateIpAllocationMethod = "Static"
        $VMNIC.IpConfigurations[0].PrivateIpAddress = $VMIP
        Set-AzNetworkInterface -NetworkInterface $VMNIC

        Write-Verbose "Building VM Config"
        #If($VMAS)
        #{
        #$vmConfig = New-AzVMConfig -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-AzVMConfig @vmConfigParams
        #}

        
        
        $vmConfig | Set-AzVMOSDisk -Name $VMOSDiskName -CreateOption FromImage
        If ($VMOS -eq "Windows") {
            $vmConfig | Set-AzVMOperatingSystem -Windows -ComputerName $VMName -Credential $VMCredential
            $vmConfig | Set-AzVMSourceImage -PublisherName $VMPublisher -Offer $VMOffer -Skus $VMSku -Version latest
        }
        If ($VMOS -eq "Linux") {
            $vmConfig | Set-AzVMOperatingSystem -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-AzVMSourceImage -Id "/subscriptions/76297098-764c-43de-8525-c9fda1b237be/resourceGroups/rg-infra-templates-tst-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-103" }
                "infra01" { $vmConfig | Set-AzVMSourceImage -Id "/subscriptions/e53aa0c7-824d-40a2-b420-4ab77b1051d2/resourceGroups/rg-infra-templates-prd-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-403" }
                "prd01" { $vmConfig | Set-AzVMSourceImage -Id "/subscriptions/437b2bfa-850e-4464-b6c2-38a68cda7c69/resourceGroups/rg-infra-templates-prd-002/providers/Microsoft.Compute/images/vm-rhel74template-prd-003" }
            }
        }
        
        $vmConfig | Add-AzVMNetworkInterface -Id $VMNIC.ID
        #$vmConfig | Set-AzureRmVMBootDiagnostics -Enable -ResourceGroupName $ResourceGroup -StorageAccountName $VMDiagStorageAcct
        ##set to use managed storage account after module conversion to Az
        #$vmConfig | Set-AzVMBootDiagnostic -VM $vmConfig -Enable -ResourceGroupName $ResourceGroup
        Set-AzVMBootDiagnostic -VM $vmConfig -Enable -ResourceGroupName $ResourceGroup
        
        Write-Verbose "Creating VM"
        New-AzVM -VM $vmConfig -ResourceGroupName $resourceGroup -Location $VMLocation -DisableBginfoExtension -LicenseType "Windows_Server" -AsJob

    }
    End {
    }
}

function Add-ITDAzureRMNewDataDisk {
    [CmdletBinding()]
    Param
    (
        [string]
        $VMName,

        [int[]]
        $SizeGB
    )

    Begin {
        $search = @()
        $Hostname = $VMName.split('-')[1]
        $Environment = $VMName.split('-')[2]

        Get-AzSubscription | ForEach-Object {
            $Subscription = $_
            Set-AzContext $_ | Out-Null
            $search += Get-AzVM | Where-Object Name -EQ $VMName | Select-Object *, @{n = 'SubscriptionName'; e = { $Subscription.Name } }
        }
    }
    Process {
        If ($search.count -eq 1) {
            Set-AzContext $search.SubscriptionName
            $ResourceGroup = $search.ResourceGroupName.ToLower()
            $Location = (Get-AzResourceGroup -Name $ResourceGroup).Location
            $VM = Get-AzVM -Name $VMName -ResourceGroupName $ResourceGroup
            $Zone = $VM.Zones
    

            ForEach ($Size in $SizeGB) {
                $ExistingDisks = @($VM.StorageProfile.DataDisks | Select-Object *, @{n = 'ItdId'; e = { [int]($_.Name -replace "vm-$hostname-app-$environment-") } })
    
                $NewDiskItdIdInt = ($ExistingDisks | Sort-Object ItdId -Descending | Select-Object -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-AzDiskConfig @AzureRmDiskConfigParams

                If (!(Get-AzDisk -ResourceGroupName $ResourceGroup -DiskName $NewDiskName -ErrorAction SilentlyContinue)) {
                    $NewDisk = New-AzDisk -DiskName $NewDiskName -Disk $DiskConfig -ResourceGroupName $ResourceGroup
            
                    $VM = Add-AzVMDataDisk -Name $NewDiskName -CreateOption Attach -ManagedDiskId $NewDisk.Id -VM $VM -Lun $LunID -Caching ReadOnly
                    Update-AzVM -VM $VM -ResourceGroupName $ResourceGroup -AsJob
                }   
            }           
        }
        Else {
            Write-Error "Search count invalid" -ErrorAction SilentlyContinue
        }
    }
    End {
    }
}

$IaasAutoCred = Get-AutomationPSCredential -Name 'ITD Iaas Automation' 

$IaasAutoCred = $IaaSAutoAz
<#
New-ITDAzureWindowsVMAA `
    -ComputerName itdbuilddba.nd.gov `
    -CPU 2 `
    -MemoryGB 8 `
    -Subnet '10.21.8.0/22'`
    -OS 'Windows Server 2019 Datacenter' `
    -Environment 'Test' `
    -AppName 'Infra-SoftDev-TFS' `
    -LicensingRestrictions 'No Licensing Restrictions' `
    -verbose
#>

<#

$params = @{
    ComputerName = "itdpurshir1.nd.gov"
    CPU = 2;
    MemoryGB = 8;
    Subnet = '10.69.254.0/24';
    OS = 'Windows Server 2022 Datacenter';
    Environment = 'CARES-tst';
    AppName = 'ITD-POC-Purview';
    LicensingRestrictions = 'No Licensing Restrictions';
    Verbose = $true;
}

New-ITDAzureWindowsVMAA @params
#>
$params = @{
    ComputerName = "itdsoscmtsql22.nd.gov"
    CPU = 4;
    MemoryGB = 16;
    Subnet = '10.21.8.0/22';
    OS = 'Windows Server 2022 Datacenter';
    Environment = 'Test';
    AppName = 'SOS-BLS';
    LicensingRestrictions = 'Microsoft SQL Standard';
    Verbose = $true;
}

New-ITDAzureWindowsVMAA @params



#>