In the enterprise, more and more Microsoft services are being outsourced to their in-house cloud solutions: Microsoft365/Azure/Entra. This may be indignant, but it's a fact. The use of PowerShell to administer these things is almost mandatory, and to open a PowerShell administration console we generally authenticate with a login, a password and also the microsoft authenticator software. But how can we run scripts that will be launched automatically and will therefore require authentication without any human interaction? Well, that's exactly what I'm going to explain in this article: how to authenticate to ExchangeOnlineManagement and AzureAD with PowerShell without a password.
Make sure you have a version of .Net at least equal to 4.7.2 and Tls with version 1.2. For example from a Windows 2016 server, I had to update my .Net version and enable Tls to 1.2.
PS C:\> [Net.ServicePointManager]::SecurityProtocol
Ssl3, Tls
PS C:\> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
PS C:\> [Net.ServicePointManager]::SecurityProtocol
Tls12
If (-Not (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319'))
{
New-Item 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319' -Force | Out-Null
}
New-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319' -Name 'SystemDefaultTlsVersions' -Value '1' -PropertyType 'DWord' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -PropertyType 'DWord' -Force | Out-Null
If (-Not (Test-Path 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319'))
{
New-Item 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319' -Force | Out-Null
}
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319' -Name 'SystemDefaultTlsVersions' -Value '1' -PropertyType 'DWord' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -PropertyType 'DWord' -Force | Out-Null
If (-Not (Test-Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server'))
{
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force | Out-Null
}
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Name 'Enabled' -Value '1' -PropertyType 'DWord' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Name 'DisabledByDefault' -Value '0' -PropertyType 'DWord' -Force | Out-Null
If (-Not (Test-Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client'))
{
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force | Out-Null
}
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Name 'Enabled' -Value '1' -PropertyType 'DWord' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Name 'DisabledByDefault' -Value '0' -PropertyType 'DWord' -Force | Out-Null
We will need a certificate to authenticate our script. So we're going to create one on the computer on which we want to run the script automatically.
PS C:\> $cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -NotAfter (Get-Date).AddYears(10) -Subject "CN=Office365Automation" -KeySpec KeyExchange
PS C:\> $cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -eq "CN=Office365Automation" }
PS C:\> Export-Certificate -Cert $cert -FilePath "C:\mycert.cer"
Everything has been configured on the Entra portal, so we can now open a PowerShell prompt (with administrator rights) to connect to Exchange Online Management and AzureAd without needing a password.
PS C:\> Install-Module -name ExchangeOnlineManagement
PS C:\> Install-Module -name Microsoft.Graph
PS C:\> Import-Module ExchangeOnlineManagement
Import-Module : File C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\3.4.0\netFramework\ExchangeOnlineManagement.psm1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ Import-Module ExchangeOnlineManagement
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [Import-Module], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess,Microsoft.PowerShell.Commands.ImportModuleCommand
PS C:\> PowerShell.exe -ExecutionPolicy Unrestricted
PS C:\> Import-Module ExchangeOnlineManagement
PS C:\> Import-Module Microsoft.Graph
PS C:\> Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -eq "CN=Office365Automation" } | Select-Object Thumbprint
Thumbprint
----------
05E5C016FA061E38265D863F04C6CAFC674C84B0
PS C:\> Connect-ExchangeOnline -CertificateThumbprint "05E5C016FA061E38265D863F04C6CAFC674C84B0" -AppId "0fe06d0b-XXXXXX-XXXX-XXXX-XXXXXXXXXXXX" -Organization "XXX.onmicrosoft.com"
PS C:\> Connect-MgGraph -CertificateThumbprint "05E5C016FA061E38265D863F04C6CAFC674C84B0" -ApplicationId "0fe06d0b-XXXXXX-XXXX-XXXX-XXXXXXXXXXXX" -Tenant "XXX.onmicrosoft.com" -NoWelcome
Once logged in, we should be able to create Office365 accounts and set AzureAD rights.
PS C:\> New-Mailbox -Name "Jane Doe" -DisplayName "Jane Doe" -MicrosoftOnlineServicesID "jane.doe@STD.onmicrosoft.com" -Password (ConvertTo-SecureString -String "P@ssW0rDSuXX" -AsPlainText -Force) -FirstName "Jane" -LastName "Doe"
PS C:\> Set-Mailbox -Identity "Jane Doe" -Office "In Hell To Pay"
PS C:\> Update-MgUser -UserId "jane.doe@STD.onmicrosoft.com" -PasswordProfile @{ Password = "P@ssW0rDSuXX"; ForceChangePasswordNextSignIn= $true } -Department "In Hell To Pay" -UsageLocation "US"
Contact :