<commit_before><#
    creates new azurermadapplication for use with logging in to azurerm using password or cert
    to enable script execution, you may need to Set-ExecutionPolicy Bypass -Force

    # can be used with scripts for example
    # connect-azurermaccount -ServicePrincipal -CertificateThumbprint $cert.Thumbprint -ApplicationId $app.ApplicationId -TenantId $tenantId
    # requires free AAD base subscription
    # https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal#provide-credentials-through-automated-powershell-script
    
    example command:
    iwr https://tinyurl.com/create-azure-client-id | iex

    example command to save and/or pass arguments:
    (new-object net.webclient).downloadfile("https://raw.githubusercontent.com/jagilber/powershellScripts/master/azure-rm-create-aad-application-spn.ps1","$(get-location)\azure-rm-create-aad-application-spn.ps1");
    then:
    .\azure-rm-create-aad-application-spn.ps1 -aadDisplayName azure-rm-rest-logon -logontype certthumb
    or
    .\azure-rm-create-aad-application-spn.ps1 
    
    # 181108
#>
param(
    [pscredential]$credentials,
    #[Parameter(Mandatory = $true)]
    [string]$aadDisplayName = "azure-rm-rest-logon/$($env:Computername)",
    [string]$uri,
    [switch]$list,
    [string]$pfxPath = "$($env:temp)\$($aadDisplayName).pfx",
    #[Parameter(Mandatory = $true)][ValidateSet('cert', 'key', 'password', '<PASSWORD>')]
    [string]$logonType = 'certthumb'
)

# ----------------------------------------------------------------------------------------------------------------
function main()
{
    $keyCredential = $null
    $thumbprint = $null
    $ClientSecret = $null
    $keyvalue
    $error.Clear()

    # authenticate
    try
    {
        get-command connect-azurermaccount | Out-Null
    }
    catch [management.automation.commandNotFoundException]
    {
        if ((read-host "azurerm not installed but is required for this script. is it ok to install?[y|n]") -imatch "y")
        {
            write-host "installing minimum required azurerm modules..."
            install-module azurerm.profile
            install-module azurerm.resources
            import-module azurerm.profile
            import-module azurerm.resources
        }
        else
        {
            return 1
        }
    }
    
    if (!(Get-AzureRmContext))
    {
        connect-azurermaccount
    
        if (!(Get-AzureRmContext))
        {
            Write-Warning "unable to authenticate to azurerm. returning..."
            return 1
        }
    }

    if (!$uri)
    {
        $uri = "https://$($aadDisplayName)"
    }

    $tenantId = (Get-AzureRmContext).Tenant.Id

    if ((Get-AzureRmADApplication -DisplayNameStartWith $aadDisplayName -ErrorAction SilentlyContinue))
    {
        $app = Get-AzureRmADApplication -DisplayNameStartWith $aadDisplayName

        if ((read-host "AAD application exists: $($aadDisplayName). Do you want to delete?[y|n]") -imatch "y")
        {
            remove-AzureRmADApplication -objectId $app.objectId -Force
        
            $id = Get-AzureRmADServicePrincipal -SearchString $aadDisplayName
        
            if (@($id).Count -eq 1)
            {
                Remove-AzureRmADServicePrincipal -ObjectId $id
            }
        }
    }
    
    if (!$list)
    {
        if ($logontype -ieq 'cert')
        {
            Write-Warning "this option is NOT currently working for rest authentication, but does work for ps auth!!!"
            $cert = New-SelfSignedCertificate -CertStoreLocation "cert:\currentuser\My" -Subject "CN=$($aadDisplayName)" -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"
            
            if (!$credentials)
            {
                $credentials = (get-credential)
            }

            $pwd = ConvertTo-SecureString -String $credentials.Password -Force -AsPlainText

            if([io.file]::Exists($pfxPath))
            {
                [io.file]::Delete($pfxPath)
            }

            Export-PfxCertificate -cert "cert:\currentuser\my\$($cert.thumbprint)" -FilePath $pfxPath -Password $pwd
            $cert509 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate($pfxPath, $pwd)
            $thumbprint = $cert509.thumbprint
            $keyValue = [System.Convert]::ToBase64String($cert509.GetCertHash())
            write-host "New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue $keyValue -EndDate $cert.NotAfter -StartDate $cert.NotBefore"

            if($oldAdApp = Get-AzureRmADApplication -DisplayNameStartWith $aadDisplayName)
            {
                remove-AzureRmADApplication -ObjectId $oldAdApp.objectId
            }
            
            $DebugPreference = "Continue"    
            write-host "New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue $keyValue -EndDate $($cert.NotAfter) -StartDate $($cert.NotBefore) -verbose"
            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue ($cert.GetRawCertData()) -EndDate ($cert.NotAfter) -StartDate ($cert.NotBefore) -verbose #-Debug 
            $app            
            #$DebugPreference = "SilentlyContinue"
            $app = New-AzureRmADAppCredential -applicationId ($app.ApplicationId) -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -KeyCredentials $KeyCredential -Verbose

        }
        elseif ($logontype -ieq 'certthumb')
        {
            
            $cert = New-SelfSignedCertificate -CertStoreLocation "cert:\currentuser\My" -Subject "$($aadDisplayName)" -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"
            $keyValue = [System.Convert]::ToBase64String($cert.GetCertHash())
            write-host "New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue $keyValue -EndDate $cert.NotAfter -StartDate $cert.NotBefore"
            $thumbprint = $cert.Thumbprint
            $ClientSecret = [System.Convert]::ToBase64String($cert.GetCertHash())
            $pwd = ConvertTo-SecureString -String $ClientSecret -Force -AsPlainText
            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -Password $<PASSWORD> -EndDate ($cert.NotAfter)
        }
        elseif ($logontype -ieq 'key')
        {
            $bytes = New-Object Byte[] 32
            $rand = [System.Security.Cryptography.RandomNumberGenerator]::Create()
            $rand.GetBytes($bytes)

            $ClientSecret = [System.Convert]::ToBase64String($bytes)
            $pwd = ConvertTo-SecureString -String $ClientSecret -Force -AsPlainText
            $endDate = [System.DateTime]::Now.AddYears(2)

            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $URI -IdentifierUris $URI -Password $pwd -EndDate $endDate
            write-host "client secret: $($ClientSecret)" -ForegroundColor Yellow

        }
        else
        {
            write-warning "credentials need to be psadcredentials to work"
            if (!$credentials)
            {
                write-warning "no credentials, exiting"
                exit 1
            }
            # to use password
            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -PasswordCredentials $credentials
        }

        $app
        
        New-AzureRmADServicePrincipal -ApplicationId ($app.ApplicationId) -DisplayName $aadDisplayName
        
        Start-Sleep 15
        New-AzureRmRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName ($app.ApplicationId)
        New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName ($app.ApplicationId)
        

        if ($logontype -ieq 'cert' -or $logontype -ieq 'certthumb')
        {
            write-host "for use in script: connect-azurermaccount -ServicePrincipal -CertificateThumbprint $($cert.Thumbprint) -ApplicationId $($app.ApplicationId) -TenantId $($tenantId)"
            write-host "certificate thumbprint: $($cert.Thumbprint)"
            
        }
    } 

    $app<commit_msg>add check for existing cert<commit_after><#
    creates new azurermadapplication for use with logging in to azurerm using password or cert
    to enable script execution, you may need to Set-ExecutionPolicy Bypass -Force

    # can be used with scripts for example
    # connect-azurermaccount -ServicePrincipal -CertificateThumbprint $cert.Thumbprint -ApplicationId $app.ApplicationId -TenantId $tenantId
    # requires free AAD base subscription
    # https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal#provide-credentials-through-automated-powershell-script
    
    example command:
    iwr https://tinyurl.com/create-azure-client-id | iex

    example command to save and/or pass arguments:
    (new-object net.webclient).downloadfile("https://raw.githubusercontent.com/jagilber/powershellScripts/master/azure-rm-create-aad-application-spn.ps1","$(get-location)\azure-rm-create-aad-application-spn.ps1");
    then:
    .\azure-rm-create-aad-application-spn.ps1 -aadDisplayName azure-rm-rest-logon -logontype certthumb
    or
    .\azure-rm-create-aad-application-spn.ps1 
    
    # 181108
#>
param(
    [pscredential]$credentials,
    #[Parameter(Mandatory = $true)]
    [string]$aadDisplayName = "azure-rm-rest-logon/$($env:Computername)",
    [string]$certStore = "cert:\CurrentUser\My",
    [string]$uri,
    [switch]$list,
    [string]$pfxPath = "$($env:temp)\$($aadDisplayName).pfx",
    #[Parameter(Mandatory = $true)][ValidateSet('cert', 'key', 'password', 'certthumb')]
    [string]$logonType = 'certthumb'
)

# ----------------------------------------------------------------------------------------------------------------
function main()
{
    $retryCount = 10
    $cert = $null
    $keyCredential = $null
    $thumbprint = $null
    $ClientSecret = $null
    $keyvalue = $Null
    $error.Clear()

    # authenticate
    try
    {
        get-command connect-azurermaccount | Out-Null
    }
    catch [management.automation.commandNotFoundException]
    {
        if ((read-host "azurerm not installed but is required for this script. is it ok to install?[y|n]") -imatch "y")
        {
            write-host "installing minimum required azurerm modules..."
            install-module azurerm.profile
            install-module azurerm.resources
            import-module azurerm.profile
            import-module azurerm.resources
        }
        else
        {
            return 1
        }
    }
    
    if (!(Get-AzureRmContext))
    {
        connect-azurermaccount
    
        if (!(Get-AzureRmContext))
        {
            Write-Warning "unable to authenticate to azurerm. returning..."
            return 1
        }
    }

    if (!$uri)
    {
        $uri = "https://$($aadDisplayName)"
    }

    $tenantId = (Get-AzureRmContext).Tenant.Id

    if ((Get-AzureRmADApplication -DisplayNameStartWith $aadDisplayName -ErrorAction SilentlyContinue))
    {
        $app = Get-AzureRmADApplication -DisplayNameStartWith $aadDisplayName

        if ((read-host "AAD application exists: $($aadDisplayName). Do you want to delete?[y|n]") -imatch "y")
        {
            remove-AzureRmADApplication -objectId $app.objectId -Force
        
            $id = Get-AzureRmADServicePrincipal -SearchString $aadDisplayName
        
            if (@($id).Count -eq 1)
            {
                Remove-AzureRmADServicePrincipal -ObjectId $id
            }
        }
    }

    $certs = @(Get-ChildItem $certStore | Where-Object {$_.Subject -imatch "$($aadDisplayName)" -and $_.NotAfter -gt (get-date)})

    if($certs.Count -ge 1)
    {
        $count = 1

        foreach($certItem in $certs)
        {
            "$($count). $($certItem.Subject) $($certItem.NotAfter) $($certItem.Thumbprint)"
            $count++
        }

        if(($result = read-host "enter line number of existing cert to use or 0 to create new") -gt 0)
        {
            $cert = $certs[$result]
        }

    }
    
    if (!$list)
    {
        if ($logontype -ieq 'cert')
        {
            Write-Warning "this does not work for rest authentication, but does work for ps auth"
            
            if(!$cert)
            {
                $cert = New-SelfSignedCertificate -CertStoreLocation $certStore `
                    -Subject "CN=$($aadDisplayName)" `
                    -KeyExportPolicy Exportable `
                    -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"
            }
            
            if (!$credentials)
            {
                $credentials = (get-credential)
            }

            $pwd = ConvertTo-SecureString -String $credentials.Password -Force -AsPlainText

            if([io.file]::Exists($pfxPath))
            {
                [io.file]::Delete($pfxPath)
            }

            Export-PfxCertificate -cert "cert:\currentuser\my\$($cert.thumbprint)" -FilePath $pfxPath -Password $pwd
            $cert509 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate($pfxPath, $pwd)
            $thumbprint = $cert509.thumbprint
            $keyValue = [System.Convert]::ToBase64String($cert509.GetCertHash())
            write-host "New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue $keyValue -EndDate $cert.NotAfter -StartDate $cert.NotBefore"

            if($oldAdApp = Get-AzureRmADApplication -DisplayNameStartWith $aadDisplayName)
            {
                remove-AzureRmADApplication -ObjectId $oldAdApp.objectId
            }
            
            $DebugPreference = "Continue"    
            write-host "New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue $keyValue -EndDate $($cert.NotAfter) -StartDate $($cert.NotBefore) -verbose"
            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue ($cert.GetRawCertData()) -EndDate ($cert.NotAfter) -StartDate ($cert.NotBefore) -verbose #-Debug 
            $app            
            #$DebugPreference = "SilentlyContinue"
            $app = New-AzureRmADAppCredential -applicationId ($app.ApplicationId) -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -KeyCredentials $KeyCredential -Verbose

        }
        elseif ($logontype -ieq 'certthumb')
        {
            if(!$cert)
            {
                $cert = New-SelfSignedCertificate -CertStoreLocation $certStore `
                    -Subject "$($aadDisplayName)" `
                    -KeyExportPolicy Exportable `
                    -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"
            }

            $keyValue = [System.Convert]::ToBase64String($cert.GetCertHash())
            write-host "New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -CertValue $keyValue -EndDate $cert.NotAfter -StartDate $cert.NotBefore"
            $thumbprint = $cert.Thumbprint
            $ClientSecret = [System.Convert]::ToBase64String($cert.GetCertHash())
            $pwd = ConvertTo-SecureString -String $ClientSecret -Force -AsPlainText
            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -Password $<PASSWORD> -EndDate ($cert.NotAfter)
        }
        elseif ($logontype -ieq 'key')
        {
            $bytes = New-Object Byte[] 32
            $rand = [System.Security.Cryptography.RandomNumberGenerator]::Create()
            $rand.GetBytes($bytes)

            $ClientSecret = [System.Convert]::ToBase64String($bytes)
            $pwd = ConvertTo-SecureString -String $ClientSecret -Force -AsPlainText
            $endDate = [System.DateTime]::Now.AddYears(2)

            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $URI -IdentifierUris $URI -Password $pwd -EndDate $endDate
            write-host "client secret: $($ClientSecret)" -ForegroundColor Yellow

        }
        else
        {
            write-warning "credentials need to be psadcredentials to work"
            if (!$credentials)
            {
                write-warning "no credentials, exiting"
                exit 1
            }
            # to use password
            $app = New-AzureRmADApplication -DisplayName $aadDisplayName -HomePage $uri -IdentifierUris $uri -PasswordCredentials $credentials
        }

        $app
        
        New-AzureRmADServicePrincipal -ApplicationId ($app.ApplicationId) -DisplayName $aadDisplayName
        
        $count = 0

        while ($count -lt $retryCount)
        {
            try 
            {
                write-host "$($count) -- sleeping 10 seconds while vault is created and registered in dns"
                start-sleep -Seconds 10
                write-host "adding role assignments"
                New-AzureRmRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName ($app.ApplicationId)
                New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName ($app.ApplicationId)
                write-host "role assignments added"
            
                if (!$error)
                {
                    break
                }
    
            }
            catch {}
    
            write-verbose ($error | out-string)
            $error.Clear()
            $count++
        }

        if ($logontype -ieq 'cert' -or $logontype -ieq 'certthumb')
        {
            write-host "for use in script: connect-azurermaccount -ServicePrincipal -CertificateThumbprint $($cert.Thumbprint) -ApplicationId $($app.ApplicationId) -TenantId $($tenantId)"
            write-host "certificate thumbprint: $($cert.Thumbprint)"
            
        }
    } 

    $app
{'fraction_non_alphanumeric': 0.11968791500664011, 'fraction_numerical': 0.005146082337317397, 'mean_word_length': 2.187477954144621, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1871514', 'n_tokens_mistral': 5256, 'n_tokens_neox': 5056, 'n_words': 1097}