diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 1e6a0c66..ef06655b 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -14,11 +14,6 @@ jobs: uses: PowershellFrameworkCollective/psframework@32c18f13173be8cc6b6803c63c40b9d7ab5aec12 # version 1.0.12 - name: Azure.Storage uses: Azure/azure-powershell@v4.4.0-September2017 # unclear which commit/tag corresponds to https://www.powershellgallery.com/packages/Azure.Storage/4.4.0 - # AzureAd does not seem to have a public GitHub repository - # - name: AzureAd - # uses: - - name: PSNotification - uses: Splaxi/PSNotification@b344c3dfdb04db1a338f203d1a0c5ae72d67ae89 # version 0.5.3 - name: PSOAuthHelper uses: Splaxi/PSOAuthHelper@837a2da63bf76e86f339a4e43e38df5a3b82affe # version 0.3.0 - name: ImportExcel diff --git a/build/vsts-prerequisites.ps1 b/build/vsts-prerequisites.ps1 index 4e822b9f..22502d43 100644 --- a/build/vsts-prerequisites.ps1 +++ b/build/vsts-prerequisites.ps1 @@ -2,7 +2,7 @@ Write-Host "The user running is: $($env:UserName)" # $modules = @("PSFramework", "Az.Storage", "AzureAd", "PSNotification", "PSOAuthHelper", "PowerShellGet", "PackageManagement","ImportExcel","PSScriptAnalyzer") -$modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "AzureAd", "PSNotification", "PSOAuthHelper", "ImportExcel") +$modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "PSOAuthHelper", "ImportExcel") Write-Host "Installing Pester, maximum version 4.99.99" -ForegroundColor Cyan Install-Module "Pester" -MaximumVersion 4.99.99 -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck diff --git a/build/vsts-validate-psscriptanalyzer.ps1 b/build/vsts-validate-psscriptanalyzer.ps1 index 98892d91..d3ae8474 100644 --- a/build/vsts-validate-psscriptanalyzer.ps1 +++ b/build/vsts-validate-psscriptanalyzer.ps1 @@ -14,7 +14,7 @@ Write-Host "Working on the machine named: $($env:computername)" Write-Host "The user running is: $($env:UserName)" -$modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "AzureAd", "PSNotification", "PSOAuthHelper", "ImportExcel") +$modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "PSOAuthHelper", "ImportExcel") foreach ($item in $modules) { $module = Get-Module -Name $item -ErrorAction SilentlyContinue diff --git a/build/vsts-validate.ps1 b/build/vsts-validate.ps1 index e17d06b2..80a1f362 100644 --- a/build/vsts-validate.ps1 +++ b/build/vsts-validate.ps1 @@ -17,7 +17,7 @@ Write-Host "Working on the machine named: $($env:computername)" Write-Host "The user running is: $($env:UserName)" -$modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "AzureAd", "PSNotification", "PSOAuthHelper", "ImportExcel") +$modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "PSOAuthHelper", "ImportExcel") foreach ($item in $modules) { $module = Get-Module -Name $item -ErrorAction SilentlyContinue diff --git a/d365fo.tools/bin/d365fo.tools-index.json b/d365fo.tools/bin/d365fo.tools-index.json index 5e1f0819..d89e5add 100644 --- a/d365fo.tools/bin/d365fo.tools-index.json +++ b/d365fo.tools/bin/d365fo.tools-index.json @@ -5404,6 +5404,22 @@ true, "false", "" + ], + [ + "EmailValue", + "Specify which field to use as EMAIL value when importing the users.\r\nAvailable options \u0027Mail\u0027 / \u0027UserPrincipalName\u0027\nDefault is \u0027Mail\u0027", + "", + false, + "false", + "Mail" + ], + [ + "TenantId", + "The TenantId to use when connecting to Azure Active Directory\nUses the tenant id of the current environment if not specified.", + "", + false, + "false", + "$Script:TenantId" ] ], "Alias": "", @@ -5411,8 +5427,8 @@ "Synopsis": "Used to import Aad users into D365FO", "Name": "Import-D365AadUser", "Links": null, - "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\"\nImports Claire and Allen as users\n-------------------------- EXAMPLE 2 --------------------------\nPS C:\\\u003e$myPassword = ConvertTo-SecureString \"MyPasswordIsSecret\" -AsPlainText -Force\nPS C:\\\u003e $myCredentials = New-Object System.Management.Automation.PSCredential (\"MyEmailIsAlso\", $myPassword)\nPS C:\\\u003e Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -AzureAdCredential $myCredentials\nThis will import Claire and Allen as users.\n-------------------------- EXAMPLE 3 --------------------------\nPS C:\\\u003eImport-D365AadUser -AadGroupName \"CustomerTeam1\"\nif more than one group match the AadGroupName, you can use the ExactAadGroupName parameter\r\nImport-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\n-------------------------- EXAMPLE 4 --------------------------\nPS C:\\\u003eImport-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\nThis is used to force the cmdlet to find the exact named group in Azure Active Directory.\n-------------------------- EXAMPLE 5 --------------------------\nPS C:\\\u003eImport-D365AadUser -AadGroupId \"99999999-aaaa-bbbb-cccc-9999999999\"\nImports all the users that is present in the AAD Group called CustomerTeam1\n-------------------------- EXAMPLE 6 --------------------------\nPS C:\\\u003eImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -SkipAzureAd\nImports Claire and Allen as users.\r\nWill NOT make you connect to the Azure Active Directory(AAD).\r\nThe needed details will be based on the e-mail address only, and the rest will be blanked.", - "Syntax": "Import-D365AadUser [-Users] \u003cString[]\u003e [[-StartupCompany] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-IdPrefix] \u003cString\u003e] [[-NameSuffix] \u003cString\u003e] [[-IdValue] \u003cString\u003e] [[-NameValue] \u003cString\u003e] [[-AzureAdCredential] \u003cPSCredential\u003e] [[-SkipAzureAd]] [\u003cCommonParameters\u003e]\nImport-D365AadUser [-AadGroupName] \u003cString\u003e [[-StartupCompany] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-IdPrefix] \u003cString\u003e] [[-NameSuffix] \u003cString\u003e] [[-IdValue] \u003cString\u003e] [[-NameValue] \u003cString\u003e] [[-AzureAdCredential] \u003cPSCredential\u003e] [[-ForceExactAadGroupName]] [\u003cCommonParameters\u003e]\nImport-D365AadUser [[-StartupCompany] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-IdPrefix] \u003cString\u003e] [[-NameSuffix] \u003cString\u003e] [[-IdValue] \u003cString\u003e] [[-NameValue] \u003cString\u003e] [[-AzureAdCredential] \u003cPSCredential\u003e] [-AadGroupId] \u003cString\u003e [\u003cCommonParameters\u003e]" + "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\"\nImports Claire and Allen as users\n-------------------------- EXAMPLE 2 --------------------------\nPS C:\\\u003e$myPassword = ConvertTo-SecureString \"MyPasswordIsSecret\" -AsPlainText -Force\nPS C:\\\u003e $myCredentials = New-Object System.Management.Automation.PSCredential (\"MyEmailIsAlso\", $myPassword)\nPS C:\\\u003e Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -AzureAdCredential $myCredentials\nThis will import Claire and Allen as users.\n-------------------------- EXAMPLE 3 --------------------------\nPS C:\\\u003eImport-D365AadUser -AadGroupName \"CustomerTeam1\"\nif more than one group match the AadGroupName, you can use the ExactAadGroupName parameter\r\nImport-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\n-------------------------- EXAMPLE 4 --------------------------\nPS C:\\\u003eImport-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\nThis is used to force the cmdlet to find the exact named group in Azure Active Directory.\n-------------------------- EXAMPLE 5 --------------------------\nPS C:\\\u003eImport-D365AadUser -AadGroupId \"99999999-aaaa-bbbb-cccc-9999999999\"\nImports all the users that is present in the AAD Group called CustomerTeam1\n-------------------------- EXAMPLE 6 --------------------------\nPS C:\\\u003eImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -SkipAzureAd\nImports Claire and Allen as users.\r\nWill NOT make you connect to the Azure Active Directory(AAD).\r\nThe needed details will be based on the e-mail address only, and the rest will be blanked.\n-------------------------- EXAMPLE 7 --------------------------\nPS C:\\\u003eImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -TenantId \"99999999-aaaa-bbbb-cccc-9999999999\"\nImports Claire and Allen as users. Uses tenant id \"99999999-aaaa-bbbb-cccc-9999999999\"\r\nwhen connecting to Azure Active Directory(AAD).", + "Syntax": "Import-D365AadUser [-Users] \u003cString[]\u003e [[-StartupCompany] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-IdPrefix] \u003cString\u003e] [[-NameSuffix] \u003cString\u003e] [[-IdValue] \u003cString\u003e] [[-NameValue] \u003cString\u003e] [[-AzureAdCredential] \u003cPSCredential\u003e] [[-SkipAzureAd]] [[-EmailValue] \u003cString\u003e] [[-TenantId] \u003cString\u003e] [\u003cCommonParameters\u003e]\nImport-D365AadUser [-AadGroupName] \u003cString\u003e [[-StartupCompany] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-IdPrefix] \u003cString\u003e] [[-NameSuffix] \u003cString\u003e] [[-IdValue] \u003cString\u003e] [[-NameValue] \u003cString\u003e] [[-AzureAdCredential] \u003cPSCredential\u003e] [[-ForceExactAadGroupName]] [[-EmailValue] \u003cString\u003e] [[-TenantId] \u003cString\u003e] [\u003cCommonParameters\u003e]\nImport-D365AadUser [[-StartupCompany] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-IdPrefix] \u003cString\u003e] [[-NameSuffix] \u003cString\u003e] [[-IdValue] \u003cString\u003e] [[-NameValue] \u003cString\u003e] [[-AzureAdCredential] \u003cPSCredential\u003e] [-AadGroupId] \u003cString\u003e [[-EmailValue] \u003cString\u003e] [[-TenantId] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Import-D365Bacpac", diff --git a/d365fo.tools/d365fo.tools.psd1 b/d365fo.tools/d365fo.tools.psd1 index 42054bbb..7acdeb3e 100644 --- a/d365fo.tools/d365fo.tools.psd1 +++ b/d365fo.tools/d365fo.tools.psd1 @@ -30,7 +30,6 @@ RequiredModules = @( @{ ModuleName = 'PSFramework'; ModuleVersion = '1.0.12' } , @{ ModuleName = 'Az.Storage'; ModuleVersion = '1.11.0' } - , @{ ModuleName = 'AzureAd'; ModuleVersion = '2.0.1.16' } , @{ ModuleName = 'PSOAuthHelper'; ModuleVersion = '0.3.0' } , @{ ModuleName = 'ImportExcel'; ModuleVersion = '7.1.0' } ) diff --git a/d365fo.tools/functions/import-d365aaduser.ps1 b/d365fo.tools/functions/import-d365aaduser.ps1 index abf0ea94..8f139be9 100644 --- a/d365fo.tools/functions/import-d365aaduser.ps1 +++ b/d365fo.tools/functions/import-d365aaduser.ps1 @@ -63,6 +63,17 @@ .PARAMETER AadGroupId Azure Active directory user group ID containing users to be imported + .PARAMETER EmailValue + Specify which field to use as EMAIL value when importing the users. + Available options 'Mail' / 'UserPrincipalName' + + Default is 'Mail' + + .PARAMETER TenantId + The TenantId to use when connecting to Azure Active Directory + + Uses the tenant id of the current environment if not specified. + .EXAMPLE PS C:\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" @@ -99,6 +110,12 @@ Will NOT make you connect to the Azure Active Directory(AAD). The needed details will be based on the e-mail address only, and the rest will be blanked. + .EXAMPLE + PS C:\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -TenantId "99999999-aaaa-bbbb-cccc-9999999999" + + Imports Claire and Allen as users. Uses tenant id "99999999-aaaa-bbbb-cccc-9999999999" + when connecting to Azure Active Directory(AAD). + .NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups @@ -106,6 +123,8 @@ Author: Charles Colombel (@dropshind) Author: Mötz Jensen (@Splaxi) Author: Miklós Molnár (@scifimiki) + Author: Gert Van der Heyden (@gertvdh) + Author: Florian Hopfner (@FH-Inway) At no circumstances can this cmdlet be used to import users into a PROD environment. @@ -164,7 +183,14 @@ function Import-D365AadUser { [switch] $ForceExactAadGroupName, [Parameter(Mandatory = $true, Position = 14, ParameterSetName = "GroupIdImport")] - [string] $AadGroupId + [string] $AadGroupId, + + [Parameter(Mandatory = $false, Position = 15)] + [ValidateSet('Mail', 'UserPrincipalName')] + [string] $EmailValue = "Mail", + + [Parameter(Mandatory = $false, Position = 16)] + [string] $TenantId = $Script:TenantId ) $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters @@ -179,14 +205,14 @@ function Import-D365AadUser { $canonicalProvider = Get-CanonicalIdentityProvider try { - Write-PSFMessage -Level Verbose -Message "Trying to connect to the Azure Active Directory" + Write-PSFMessage -Level Verbose -Message "Trying to connect to the Azure Active Directory with tenant id '$TenantId'" if ($PSBoundParameters.ContainsKey("AzureAdCredential") -eq $true) { - $null = Connect-AzureAD -ErrorAction Stop -Credential $AzureAdCredential + Connect-AzAccount -Credential $AzureAdCredential -ErrorAction Stop -TenantId $TenantId } else { if ($SkipAzureAd -eq $false) { - $null = Connect-AzureAD -ErrorAction Stop + Connect-AzAccount -ErrorAction Stop -TenantId $TenantId } } } @@ -202,16 +228,31 @@ function Import-D365AadUser { if ($PSCmdlet.ParameterSetName -eq 'GroupIdImport') { Write-PSFMessage -Level Verbose -Message "Search AadGroup by its ID : $AadGroupId" - $group = Get-AzureADGroup -ObjectId $AadGroupId + + $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups/$AadGroupId" + + if ($resObj.StatusCode -like "2**") { + $group = $resObj.Content | ConvertFrom-Json + } } else { if ($ForceExactAadGroupName) { Write-PSFMessage -Level Verbose -Message "Search AadGroup by its exactly name : $AadGroupName" - $group = Get-AzureADGroup -Filter "DisplayName eq '$AadGroupName'" + + $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups?`$filter=DisplayName eq '$AadGroupName'" + + if ($resObj.StatusCode -like "2**") { + $group = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value + } } else { Write-PSFMessage -Level Verbose -Message "Search AadGroup by searching with its name : $AadGroupName" - $group = Get-AzureADGroup -SearchString $AadGroupName + + $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups?`$filter=startswith(DisplayName,'$AadGroupName')" + + if ($resObj.StatusCode -like "2**") { + $group = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value + } } } @@ -233,16 +274,22 @@ function Import-D365AadUser { return } - $userlist = Get-AzureADGroupMember -ObjectId $group[0].ObjectId + $resMembersObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups/$($group.id)/members" + + if ($resMembersObj.StatusCode -like "2**") { + $userlist = $resMembersObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value + } foreach ($user in $userlist) { - if ($user.ObjectType -eq "User") { - $azureAdUser = Get-AzureADUser -ObjectId $user.ObjectId - if ($null -eq $azureAdUser.Mail) { + if ($user.'@odata.type' -eq "#microsoft.graph.user") { + + $azureAdUser = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/users/$($user.id)" + + if ($null -eq $azureAdUser.mail) { Write-PSFMessage -Level Critical "User $($user.ObjectId) did not have an Mail" } else { - $null = $azureAdUsers.Add((Get-AzureADUser -ObjectId $user.ObjectId)) + $null = $azureAdUsers.Add($azureAdUser) } } } @@ -253,14 +300,19 @@ function Import-D365AadUser { if ($SkipAzureAd -eq $true) { $name = Get-LoginFromEmail $user $null = $azureAdUsers.Add([PSCustomObject]@{ - Mail = $user - GivenName = $name - DisplayName = $name - ObjectId = '' + mail = $user + givenName = $name + displayName = $name + ObjectId = '' + userPrincipalName = $user }) } else { - $aadUser = Get-AzureADUser -SearchString $user + $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/users?`$filter=mail eq '$user' or userPrincipalName eq '$user'" + + if ($resObj.StatusCode -like "2**") { + $aadUser = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value | Select-Object -First 1 + } if ($null -eq $aadUser) { Write-PSFMessage -Level Critical "Could not find user $user in AzureAAd" @@ -305,7 +357,7 @@ function Import-D365AadUser { if ($IdValue -eq 'Login') { $id = $IdPrefix + $(Get-LoginFromEmail $user.Mail) } - elseif($IdValue -eq 'UserPrincipalName') { + elseif ($IdValue -eq 'UserPrincipalName') { $id = $IdPrefix + $user.UserPrincipalName } else { @@ -314,24 +366,32 @@ function Import-D365AadUser { if ($id.Length -gt 20) { $oldId = $id - $id = $id -replace '^(.{0,20}).*','$1' + $id = $id -replace '^(.{0,20}).*', '$1' Write-PSFMessage -Level Host -Message "The id '$oldId' does not fit the 20 character limit on UserInfo table's ID field and will be truncated to '$id'" } - Write-PSFMessage -Level Verbose -Message "Id for user $($user.Mail) : $id" $name = "" if ($NameValue -eq 'DisplayName') { $name = $user.DisplayName + $NameSuffix } - else { $name = $user.GivenName + $NameSuffix } - Write-PSFMessage -Level Verbose -Message "Name for user $($user.Mail) : $name" - Write-PSFMessage -Level Verbose -Message "Importing $($user.Mail) - SID $sid - Provider $identityProvider" - Import-AadUserIntoD365FO $SqlCommand $user.Mail $name $id $sid $StartupCompany $identityProvider $networkDomain $user.ObjectId + $email = "" + if ($EmailValue -eq 'Mail') { + $email = $user.Mail + } + else { + $email = $user.UserPrincipalName + } + + Write-PSFMessage -Level Verbose -Message "Id for user $email : $id" + Write-PSFMessage -Level Verbose -Message "Name for user $email : $name" + Write-PSFMessage -Level Verbose -Message "Importing $email - SID $sid - Provider $identityProvider" + + Import-AadUserIntoD365FO $SqlCommand $email $name $id $sid $StartupCompany $identityProvider $networkDomain $user.ObjectId if (Test-PSFFunctionInterrupt) { return } } diff --git a/d365fo.tools/internal/scripts/variables.ps1 b/d365fo.tools/internal/scripts/variables.ps1 index 4bcd088f..e0b423d0 100644 --- a/d365fo.tools/internal/scripts/variables.ps1 +++ b/d365fo.tools/internal/scripts/variables.ps1 @@ -36,55 +36,61 @@ $Script:MRConfigFile = 'C:\FinancialReporting\Server\ApplicationService\bin\MRSe #Update all module variables Update-ModuleVariables +# Environment variables $environment = Get-ApplicationEnvironment -$Script:AOSPath = $environment.Aos.AppRoot +$Script:TenantId = $environment.Aad.TenantDomainGUID -$dataAccess = $environment.DataAccess +$aos = $environment.Aos +$Script:AOSPath = $aos.AppRoot +$Script:PackageDirectory = $aos.PackageDirectory +$Script:MetaDataDir = $aos.MetadataDirectory +$dataAccess = $environment.DataAccess $Script:DatabaseServer = $dataAccess.DbServer - $Script:DatabaseName = $dataAccess.Database +$Script:DatabaseUserName = $dataAccess.SqlUser +$Script:DatabaseUserPassword = $dataAccess.SqlPwd -$Script:BinDir = $environment.Common.BinDir - -$Script:PackageDirectory = $environment.Aos.PackageDirectory - -$Script:MetaDataDir = $environment.Aos.MetadataDirectory - -$Script:BinDirTools = $environment.Common.DevToolsBinDir +$common = $environment.Common +$Script:BinDir = $common.BinDir +$Script:BinDirTools = $common.DevToolsBinDir +$Script:IsOnebox = $common.IsOneboxEnvironment $Script:ServerRole = [ServerRole]::Unknown -$RoleVaule = $(If ($environment.Monitoring.MARole -eq "" -or $environment.Monitoring.MARole -eq "dev") { "Development" } Else { $environment.Monitoring.MARole }) - +$RoleVaule = $( + If ($environment.Monitoring.MARole -eq "" -or $environment.Monitoring.MARole -eq "dev") { + "Development" + } Else { + $environment.Monitoring.MARole + } +) if ($null -ne $RoleVaule) { $Script:ServerRole = [ServerRole][Enum]::Parse([type]"ServerRole", $RoleVaule, $true); } +$infrastructure = $environment.Infrastructure $Script:EnvironmentType = [EnvironmentType]::Unknown $Script:CanUseTrustedConnection = $false -if ($environment.Infrastructure.HostName -like "*cloud.onebox.dynamics.com*") { +if ($infrastructure.HostName -like "*cloud.onebox.dynamics.com*") { $Script:EnvironmentType = [EnvironmentType]::LocalHostedTier1 $Script:CanUseTrustedConnection = $true } -elseif ($environment.Infrastructure.HostName -match "(cloudax|axcloud).*dynamics.com") { +elseif ($infrastructure.HostName -match "(cloudax|axcloud).*dynamics.com") { $Script:EnvironmentType = [EnvironmentType]::AzureHostedTier1 $Script:CanUseTrustedConnection = $true } -elseif ($environment.Infrastructure.HostName -like "*sandbox.ax.dynamics.com*") { +elseif ($infrastructure.HostName -like "*sandbox.ax.dynamics.com*") { $Script:EnvironmentType = [EnvironmentType]::MSHostedTier1 $Script:CanUseTrustedConnection = $true } -elseif ($environment.Infrastructure.HostName -like "*sandbox.operations.*dynamics.com*") { +elseif ($infrastructure.HostName -like "*sandbox.operations.*dynamics.com*") { $Script:EnvironmentType = [EnvironmentType]::MSHostedTier2 } +$Script:Url = $infrastructure.HostUrl -$Script:Url = $environment.Infrastructure.HostUrl -$Script:DatabaseUserName = $dataAccess.SqlUser -$Script:DatabaseUserPassword = $dataAccess.SqlPwd $Script:Company = "DAT" -$Script:IsOnebox = $environment.Common.IsOneboxEnvironment $RegSplat = @{ Path = "HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment\" diff --git a/d365fo.tools/tests/functions/Import-D365AadUser.Tests.ps1 b/d365fo.tools/tests/functions/Import-D365AadUser.Tests.ps1 index 3a2020ad..2404cd04 100644 --- a/d365fo.tools/tests/functions/Import-D365AadUser.Tests.ps1 +++ b/d365fo.tools/tests/functions/Import-D365AadUser.Tests.ps1 @@ -206,24 +206,50 @@ $parameter.ParameterSets['GroupIdImport'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['GroupIdImport'].ValueFromRemainingArguments | Should -Be $False } + It 'Should have the expected parameter EmailValue' { + $parameter = (Get-Command Import-D365AadUser).Parameters['EmailValue'] + $parameter.Name | Should -Be 'EmailValue' + $parameter.ParameterType.ToString() | Should -Be System.String + $parameter.IsDynamic | Should -Be $False + $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' + $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' + $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 15 + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False + } + It 'Should have the expected parameter TenantId' { + $parameter = (Get-Command Import-D365AadUser).Parameters['TenantId'] + $parameter.Name | Should -Be 'TenantId' + $parameter.ParameterType.ToString() | Should -Be System.String + $parameter.IsDynamic | Should -Be $False + $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' + $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' + $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 16 + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False + } } Describe "Testing parameterset UserListImport" { <# UserListImport -Users - UserListImport -Users -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -SkipAzureAd + UserListImport -Users -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -SkipAzureAd -EmailValue -TenantId #> } Describe "Testing parameterset GroupNameImport" { <# GroupNameImport -AadGroupName - GroupNameImport -AadGroupName -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -ForceExactAadGroupName + GroupNameImport -AadGroupName -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -ForceExactAadGroupName -EmailValue -TenantId #> } Describe "Testing parameterset GroupIdImport" { <# GroupIdImport -AadGroupId - GroupIdImport -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -AadGroupId + GroupIdImport -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -AadGroupId -EmailValue -TenantId #> } diff --git a/docs/Import-D365AadUser.md b/docs/Import-D365AadUser.md index e39dd8bf..b7e0ea1a 100644 --- a/docs/Import-D365AadUser.md +++ b/docs/Import-D365AadUser.md @@ -17,7 +17,7 @@ Used to import Aad users into D365FO Import-D365AadUser [-Users] [[-StartupCompany] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-IdPrefix] ] [[-NameSuffix] ] [[-IdValue] ] [[-NameValue] ] [[-AzureAdCredential] ] - [-SkipAzureAd] [] + [-SkipAzureAd] [[-EmailValue] ] [[-TenantId] ] [] ``` ### GroupNameImport @@ -25,7 +25,7 @@ Import-D365AadUser [-Users] [[-StartupCompany] ] [[-DatabaseS Import-D365AadUser [-AadGroupName] [[-StartupCompany] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-IdPrefix] ] [[-NameSuffix] ] [[-IdValue] ] [[-NameValue] ] [[-AzureAdCredential] ] - [-ForceExactAadGroupName] [] + [-ForceExactAadGroupName] [[-EmailValue] ] [[-TenantId] ] [] ``` ### GroupIdImport @@ -33,7 +33,7 @@ Import-D365AadUser [-AadGroupName] [[-StartupCompany] ] [[-Data Import-D365AadUser [[-StartupCompany] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-IdPrefix] ] [[-NameSuffix] ] [[-IdValue] ] [[-NameValue] ] [[-AzureAdCredential] ] [-AadGroupId] - [] + [[-EmailValue] ] [[-TenantId] ] [] ``` ## DESCRIPTION @@ -90,6 +90,15 @@ Imports Claire and Allen as users. Will NOT make you connect to the Azure Active Directory(AAD). The needed details will be based on the e-mail address only, and the rest will be blanked. +### EXAMPLE 7 +``` +Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -TenantId "99999999-aaaa-bbbb-cccc-9999999999" +``` + +Imports Claire and Allen as users. +Uses tenant id "99999999-aaaa-bbbb-cccc-9999999999" +when connecting to Azure Active Directory(AAD). + ## PARAMETERS ### -AadGroupName @@ -334,6 +343,41 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -EmailValue +Specify which field to use as EMAIL value when importing the users. +Available options 'Mail' / 'UserPrincipalName' + +Default is 'Mail' + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 16 +Default value: Mail +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -TenantId +The TenantId to use when connecting to Azure Active Directory + +Uses the tenant id of the current environment if not specified. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 17 +Default value: $Script:TenantId +Accept pipeline input: False +Accept wildcard characters: False +``` + ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). @@ -348,6 +392,8 @@ Author: Rasmus Andersen (@ITRasmus) Author: Charles Colombel (@dropshind) Author: Mötz Jensen (@Splaxi) Author: Miklós Molnár (@scifimiki) +Author: Gert Van der Heyden (@gertvdh) +Author: Florian Hopfner (@FH-Inway) At no circumstances can this cmdlet be used to import users into a PROD environment.