function Connect-SPFarmToAAD { param( [Parameter(Mandatory)][String] $AADDomain, [Parameter(Mandatory)][String] $SharePointOnlineUrl, #Specify this parameter if you don't want to use the default SPWeb returned [Parameter()][String] $SharePointWeb, [Parameter()][System.Management.Automation.PSCredential] $O365Credentials, #Use these switches if you're replacing an existing connection to AAD. [Parameter()][Switch] $RemoveExistingACS, [Parameter()][Switch] $RemoveExistingSTS, [Parameter()][Switch] $RemoveExistingSPOProxy, #Use this switch if you're replacing the Office 365 SharePoint site. [Parameter()][Switch] $RemoveExistingAADCredentials, #Use this switch if you don't want to use SSL when you launch your app. [Parameter()][Switch] $AllowOverHttp ) #Prompt for credentials right away. if (-not $O365Credentials) { $O365Credentials = Get-Credential -Message "Admin credentials for $AADDomain" } Add-PSSnapin Microsoft.SharePoint.PowerShell #Import the Microsoft Online Services Sign-In Assistant. Import-Module -Name MSOnline #Import the Microsoft Online Services Module for Windows PowerShell. Import-Module MSOnlineExt -force -verbose #Set values for Constants. New-Variable -Option Constant -Name SP_APPPRINCIPALID -Value '00000003-0000-0ff1-ce00-000000000000' | Out-Null New-Variable -Option Constant -Name ACS_APPPRINCIPALID -Value '00000001-0000-0000-c000-000000000000' | Out-Null New-Variable -Option Constant -Name ACS_APPPROXY_NAME -Value ACS New-Variable -Option Constant -Name SPO_MANAGEMENT_APPPROXY_NAME -Value 'SPO Add-in Management Proxy' New-Variable -Option Constant -Name ACS_STS_NAME -Value ACS-STS New-Variable -Option Constant -Name AAD_METADATAEP_FSTRING -Value 'https://accounts.accesscontrol.windows.net/{0}/metadata/json/1' New-Variable -Option Constant -Name SP_METADATAEP_FSTRING -Value '{0}/_layouts/15/metadata/json/1' #Get the default SPWeb from the on-premises farm if no $SharePointWeb parameter is specified. if ([String]::IsNullOrEmpty($SharePointWeb)) { $SharePointWeb = Get-SPSite | Select-Object -First 1 | Get-SPWeb | Select-Object -First 1 | % Url } #Configure the realm ID for local farm so that it matches the AAD realm. $ACSMetadataEndpoint = $AAD_METADATAEP_FSTRING -f $AADDomain $ACSMetadata = Invoke-RestMethod -Uri $ACSMetadataEndpoint $AADRealmId = $ACSMetadata.realm Set-SPAuthenticationRealm -ServiceContext $SharePointWeb -Realm $AADRealmId $LocalSTS = Get-SPSecurityTokenServiceConfig $LocalSTS.NameIdentifier = '{0}@{1}' -f $SP_APPPRINCIPALID,$AADRealmId $LocalSTS.Update() #Allow connections over HTTP if the switch is specified. if ($AllowOverHttp.IsPresent -and $AllowOverHttp -eq $True) { $serviceConfig = Get-SPSecurityTokenServiceConfig $serviceConfig.AllowOAuthOverHttp = $true $serviceConfig.AllowMetadataOverHttp = $true $serviceConfig.Update() } #Step 1: Set up the ACS proxy in the on-premises SharePoint farm. Remove the existing ACS proxy #if the switch is specified. if ($RemoveExistingACS.IsPresent -and $RemoveExistingACS -eq $True) { Get-SPServiceApplicationProxy | ? DisplayName -EQ $ACS_APPPROXY_NAME | Remove-SPServiceApplicationProxy -RemoveData -Confirm:$false } if (-not (Get-SPServiceApplicationProxy | ? DisplayName -EQ $ACS_APPPROXY_NAME)) { $AzureACSProxy = New-SPAzureAccessControlServiceApplicationProxy -Name $ACS_APPPROXY_NAME -MetadataServiceEndpointUri $ACSMetadataEndpoint -DefaultProxyGroup } #Remove the existing security token service if the switch is specified. if ($RemoveExistingSTS.IsPresent) { Get-SPTrustedSecurityTokenIssuer | ? Name -EQ $ACS_STS_NAME | Remove-SPTrustedSecurityTokenIssuer -Confirm:$false } if (-not (Get-SPTrustedSecurityTokenIssuer | ? DisplayName -EQ $ACS_STS_NAME)) { $AzureACSSTS = New-SPTrustedSecurityTokenIssuer -Name $ACS_STS_NAME -IsTrustBroker -MetadataEndPoint $ACSMetadataEndpoint } #Update the ACS Proxy for OAuth authentication. $ACSProxy = Get-SPServiceApplicationProxy | ? Name -EQ $ACS_APPPROXY_NAME $ACSProxy.DiscoveryConfiguration.SecurityTokenServiceName = $ACS_APPPRINCIPALID $ACSProxy.Update() #Retrieve the local STS signing key from JSON metadata. $SPMetadata = Invoke-RestMethod -Uri ($SP_METADATAEP_FSTRING -f $SharePointWeb) $SPSigningKey = $SPMetadata.keys | ? usage -EQ "Signing" | % keyValue $CertValue = $SPSigningKey.value #Connect to Office 365. Connect-MsolService -Credential $O365Credentials #Remove existing connection to an Office 365 SharePoint site if the switch is specified. if ($RemoveExistingAADCredentials.IsPresent -and $RemoveExistingAADCredentials -eq $true) { $msolserviceprincipal = Get-MsolServicePrincipal -AppPrincipalId $SP_APPPRINCIPALID [Guid[]] $ExistingKeyIds = Get-MsolServicePrincipalCredential -ObjectId $msolserviceprincipal.ObjectId -ReturnKeyValues $false | % {if ($_.Type -ne "Other") {$_.KeyId}} Remove-MsolServicePrincipalCredential -AppPrincipalId $SP_APPPRINCIPALID -KeyIds $ExistingKeyIds } #Step 2: Upload the local STS signing certificate New-MsolServicePrincipalCredential -AppPrincipalId $SP_APPPRINCIPALID -Type Asymmetric -Value $CertValue -Usage Verify #Step 3: Add the service principal name of the local web application, if necessary. $indexHostName = $SharePointWeb.IndexOf('://') + 3 $HostName = $SharePointWeb.Substring($indexHostName) $NewSPN = '{0}/{1}' -f $SP_APPPRINCIPALID, $HostName $SPAppPrincipal = Get-MsolServicePrincipal -AppPrincipalId $SP_APPPRINCIPALID if ($SPAppPrincipal.ServicePrincipalNames -notcontains $NewSPN) { $SPAppPrincipal.ServicePrincipalNames.Add($NewSPN) Set-MsolServicePrincipal -AppPrincipalId $SPAppPrincipal.AppPrincipalId -ServicePrincipalNames $SPAppPrincipal.ServicePrincipalNames } #Remove the existing SharePoint Online proxy if the switch is specified. if ($RemoveExistingSPOProxy.IsPresent -and $RemoveExistingSPOProxy -eq $True) { Get-SPServiceApplicationProxy | ? DisplayName -EQ $SPO_MANAGEMENT_APPPROXY_NAME | Remove-SPServiceApplicationProxy -RemoveData -Confirm:$false } #Step 4: Add the SharePoint Online proxy if (-not (Get-SPServiceApplicationProxy | ? DisplayName -EQ $SPO_MANAGEMENT_APPPROXY_NAME)) { $spoproxy = New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy -Name $SPO_MANAGEMENT_APPPROXY_NAME -OnlineTenantUri $SharePointOnlineUrl -DefaultProxyGroup } }