Import File Script Guide
### A.) AD Express mapper helper script |
- script contains functions which helps user to convert the AD object search results into .csv mapping files |
- documentation will explain only the function that is correlated to AD Express mapping for EntraId for Device |
1. ADConvertToCsv function |
- helps organize the search result into .csv list files or .csv mapping files |
- called by adding to AD object search pipeline: |
<AD object search command> | ADConvertToCsv |
(AD object search commands are explained in section C.) |
- will create .csv file to the current script directory from the search result |
- if "-Path" is specified, will create file in the path (... | ADConvertToCsv -Path "C:\Users\userx\objects.csv") |
- if "-Append" switch is specified, will append existing file (must be called with -Path) |
- if "-EntraId" switch is specified, will create mapping file required by ADExpress EntraId for Device |
- supports powershell AD(on-prem) and microsoft graph (cloud) search command results |
- does not support powershell AzureAD (cloud) search command results, because of deprecated state and insufficient functionality |
### B.) INSTRUCTIONS |
1. prepare powershell window |
-for getting AD on-prem objects (section C.1.) |
- available by default |
- any version (https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps&source=recommendations) |
-for getting AD cloud objects via microsoft graph (section C.2.) |
- https://learn.microsoft.com/en-us/powershell/microsoftgraph/installation?view=graph-powershell-1.0 |
- powershell version 5.1 and higher (powershell 7 recommended) |
- powershell 7 installation guide https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4 |
2. Import script to the current powershell session |
- run powershell |
- move to directory where helper script is located (find directory/folder in UI -> shift-rightmouseclick -> "copy as path" |
"cd <directory_path>" |
- load script |
". .\BT-ADObjectMapper.ps1" |
3. Create mapping file with source (on-prem) objects filled |
-this will create .csv mapping file with source objects filled (on-prem) and empty target objects |
-this requires rights to search through on-prem AD |
-function ADConvertToCsv will require switch "-Source" and "-EntraId" to be used |
- "-Source" specifies that we want to create mapping file and fill source objects |
- "-EntraId" specifies that we want to create mapping file for "ADExpress for EntraId" |
-use section C.1. to learn about AD on-prem object search commands |
-when creating mapping file for DEVICEs, do not continue with step 4. and 5. The mapping file for DEVICEs is final with step 3. |
-structure: |
<AD object search command> | ADConvertToCsv -Source -EntraId |
-example: |
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" | ADConvertToCsv -Source -EntraId |
4. Create object file with target (cloud) objects |
-this step is required for USERs and GROUPs, not to be used for DEVICEs |
-this will create standalone file with target objects that will need to be matched with source objects in next step |
-requires rights to search through cloud AD |
-function ADConvertToCsv does not require any switch for this step |
-use section C.2. to learn about AD cloud object search commands |
-structure: |
<AD cloud object search command> | ADConvertToCsv |
-example: |
Get-MgUser -All | ADConvertToCsv |
5. Map source objects to target objects |
-this step is required for USERs and GROUPs, not to be used for DEVICEs |
-match objects in the mapping file the way you want |
-need to manually map target objects from object file created in step 4 to the source objects in the mapping file created in step 3 |
-copy respective attributes of object in the mapping file to columns prefixed with "Target" |
### C.) AD Object search commands |
#C.1. AD (on-premises) |
C.1.0 Filtering Local objects |
-Filter <query> |
specifies query string that retrieves AD objects |
-SearchBase <path> |
specifies Active Directory path to search under |
#examples: |
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" |
-gets all users (specified by -Filter *) in the container "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" |
Get-ADUser -Filter 'SamAccountName -like "*test"' -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" |
-gets all users, which have SamAccountName ending with "test" in the container "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" |
*more in doc links |
C.1.1 USER |
function: |
Get-AdUser (https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2022-ps) |
example: |
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM"| ADConvertToCsv |
C.1.2 GROUP |
function: |
Get-ADGroup (https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adgroup?view=windowsserver2022-ps) |
example: |
Get-ADGroup -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" | ADConvertToCsv |
C.1.3 DEVICE |
function: |
Get-ADComputer (https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adcomputer?view=windowsserver2022-ps) |
example: |
Get-ADComputer -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM" | ADConvertToCsv |
#C.2 AD (cloud) using Microsoft Graph |
C.2.0 Filtering Cloud objects using Microsoft Graph |
before calling any function we need to call Connect-MgGraph to connect to the azure entra id (https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/connect-mggraph?view=graph-powershell-1.0) |
-All |
returns all users |
-Filter <filter> |
allows for OData v3.0 filtering (https://www.odata.org/documentation/odata-version-3-0/odata-version-3-0-core-protocol/#queryingcollections) |
-Search <phrase> |
search items by search phrases |
-examples: |
Get-MgUser -Filter "startsWith(DisplayName, 'a')" |
-search users which displayname starts with "a" (case-insensitive) |
Get-MgUser -Search '"Mail:Peter"' |
-search users which email adress contains "Peter" |
*more in doc links |
C.2.1 USER |
function: |
Get-MgUser (https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.users/get-mguser?view=graph-powershell-1.0&preserve-view=true) |
example: |
Connect-MgGraph -Scopes 'User.Read.All' (to get permissions and choose entra id- interactive login) |
Get-MgUser -All | ADConvertToCsv |
C.2.2 GROUP |
function: |
Get-MgGroup (https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.groups/get-mggroup?view=graph-powershell-1.0) |
example: |
Connect-MgGraph -Scopes 'Group.Read.All' (to get permissions and choose entra id- interactive login) |
Get-MgGroup -All | ADConvertToCsv |
C.2.3 DEVICE |
function: |
Get-MgDevice (https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.directorymanagement/get-mgdevice?view=graph-powershell-1.0) |
example: |
Connect-MgGraph -Scopes 'Device.Read.All' (to get permissions and choose entra id- interactive login) |
Get-MgDevice -All | ADConvertToCsv |
*to switch entra id |
-disconnect |
Disconnect-MgGraph |
-connect to a different one |
Connect-MgGraph -Scopes <required_scopes> |
Import File Script
function ADConvertToCsv() #Used to convert AD(onprem/cloud) objects (users,groups,devices/computers) to a .csv list for AD Express mapping file. |
{ |
Param( |
[Parameter( |
Mandatory=$true, |
ValueFromPipeline=$true)] |
$InputObject, #Can take input from pipeline |
[Parameter(Mandatory=$false)] |
[string]$Path, #Path to output .csv file, if not provided, output will be created in current ps directory |
[Parameter(Mandatory=$false)] |
[switch]$Append, #Appends existing .csv file (-Path must be specified) |
[Parameter(Mandatory=$false)] |
[switch]$Source, #To create template mapping file with input as source objects |
[Parameter(Mandatory=$false)] |
[switch]$EntraId #To create mapping file for 'EntraID for Device' (can only be used in conjunction with -Source switch) |
) |
Begin |
{ |
#append or rewrite |
if ($Append) |
{ |
if (!$Path) |
{ |
Throw "[ERROR]: Path must be specified (-Path) in order to append existing file." |
} |
elseif (!(Test-Path $Path)) |
{ |
Throw "[ERROR]: File does not exist. It needs to exist in order to be appended." |
} |
$saveOperationType = @{ Append = $true } |
} |
else { |
$saveOperationType = @{ Force = $true } |
} |
#specify output path |
$outputPath = "" |
if ($Path) |
{ |
$outputPath = $Path |
} |
else |
{ |
if ($Source) |
{ |
$outputPath = "$PSScriptRoot\object_mapping_file_" + [DateTime]::Now.ToString('yyyy_MM_dd_HH_mm_ss') + ".csv" |
} |
else |
{ |
$outputPath = "$PSScriptRoot\object_list_" + [DateTime]::Now.ToString('yyyy_MM_dd_HH_mm_ss') + ".csv" |
} |
} |
if ($EntraId -and (-not $Source)) |
{ |
Throw "[ERROR]: Switch -EntraId can only be used in conjunction with -Source switch." |
} |
$inputList = @() |
$inputType = "" |
$uniqueDomainList = @() |
} |
Process |
{ |
if ($InputObject) |
{ |
#make sure the type is allowed and all objects are of same type |
if ($inputType -eq "") |
{ |
$inputType = $InputObject.GetType().FullName |
if ($EntraId) #switch only for on-prem objects for 'EntraID for Device' |
{ |
if ($inputType -notin @("Microsoft.ActiveDirectory.Management.ADUser", |
"Microsoft.ActiveDirectory.Management.ADGroup", |
"Microsoft.ActiveDirectory.Management.ADComputer")) |
{ |
Throw "[ERROR]: Type $inputType is not one of the accepted types." |
} |
} |
else |
{ |
if ($inputType -notin @("Microsoft.ActiveDirectory.Management.ADUser", |
"Microsoft.ActiveDirectory.Management.ADGroup", |
"Microsoft.ActiveDirectory.Management.ADComputer", |
"Microsoft.Graph.PowerShell.Models.MicrosoftGraphUser", |
"Microsoft.Graph.PowerShell.Models.MicrosoftGraphGroup", |
"Microsoft.Graph.PowerShell.Models.MicrosoftGraphDevice", |
"Microsoft.Open.AzureAD.Model.User", |
"Microsoft.Open.AzureAD.Model.Group", |
"Microsoft.Open.AzureAD.Model.Device")) |
{ |
Throw "[ERROR]: Type $inputType is not one of the accepted types." |
} |
} |
} |
elseif ($InputObject.GetType().FullName -ne $inputType) |
{ |
Throw "[ERROR]: Type $($InputObject.GetType().FullName) is not the same type as previous $inputType." |
} |
if ($EntraId) #get DC from distinguished name and get domain info |
{ |
$dnList = $InputObject.DistinguishedName -split '(?<!\\),' | Where-Object { $_ -like "DC*" } |
$dnDC = $dnList -join "," |
if ($uniqueDomainList.DNPath -notcontains $dnDC) |
{ |
$result = Get-ADDomain -Identity $dnDC |
if (-not $result) |
{ |
Throw "[ERROR]: Domain not found for object " + $InputObject.Name |
} |
$domainObject = [PSCustomObject]@{ |
DNPath = $dnDC |
NetBIOSName = $result.NetBIOSName |
DomainName = $result.Name |
} |
$uniqueDomainList += $domainObject |
} |
else |
{ |
$domainObject = $uniqueDomainList | Where-Object {$_.DNPath -eq $dnDC} |
} |
$InputObject | Add-Member -NotePropertyName NetBIOSName -NotePropertyValue $domainObject.NetBIOSName -Force |
$InputObject | Add-Member -NotePropertyName DomainName -NotePropertyValue $domainObject.DomainName -Force |
} |
$inputList += $InputObject |
} |
} |
End |
{ |
if ($inputList.Count -eq 0) |
{ |
Write-Host "[INFO]: There are no records. Csv file will not be created." |
return |
} |
#transform input into .csv file |
switch ($inputType) |
{ |
"Microsoft.ActiveDirectory.Management.ADUser" |
{ |
if ($Source) |
{ |
if ($EntraId) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SourceUserPrincipalName"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SourceSamAccountName"; Expression={$_.SamAccountName}}, ` |
@{Name="SourceNetBIOSName"; Expression={$_.NetBIOSName}}, ` |
@{Name="SourceDomainName"; Expression={$_.DomainName}}, ` |
@{Name="SourceObjectSID"; Expression={$_.SID}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetUserPrincipalName"; Expression={""}}, ` |
@{Name="TargetSamAccountName"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SourceUserPrincipalName (Optional)"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={$_.SamAccountName}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetUserPrincipalName (Optional)"; Expression={""}}, ` |
@{Name="TargetSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="UserPrincipalName"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SamAccountName"; Expression={$_.SamAccountName}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.ActiveDirectory.Management.ADGroup" |
{ |
if ($Source) |
{ |
if ($EntraId) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SourceSamAccountName"; Expression={$_.SamAccountName}}, ` |
@{Name="SourceNetBIOSName"; Expression={$_.NetBIOSName}}, ` |
@{Name="SourceDomainName"; Expression={$_.DomainName}}, ` |
@{Name="SourceObjectSID"; Expression={$_.SID}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetSamAccountName"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={$_.SamAccountName}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SamAccountName"; Expression={$_.SamAccountName}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.ActiveDirectory.Management.ADComputer" { |
if ($Source) |
{ |
if ($EntraId) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SourceSamAccountName"; Expression={$_.SamAccountName}}, ` |
@{Name="SourceDomainName"; Expression={$_.DomainName}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={$_.SamAccountName}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.ObjectGUID}}, ` |
@{Name="SamAccountName"; Expression={$_.SamAccountName}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.Graph.PowerShell.Models.MicrosoftGraphUser"{ |
if ($Source) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.Id}}, ` |
@{Name="SourceUserPrincipalName (Optional)"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={$_.OnPremisesSamAccountName}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetUserPrincipalName (Optional)"; Expression={""}}, ` |
@{Name="TargetSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.Id}}, ` |
@{Name="UserPrincipalName"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SamAccountName"; Expression={$_.OnPremisesSamAccountName}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.Graph.PowerShell.Models.MicrosoftGraphGroup"{ |
if ($Source) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.Id}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={$_.OnPremisesSamAccountName}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.Id}}, ` |
@{Name="SamAccountName"; Expression={$_.OnPremisesSamAccountName}}, ` |
@{Name="DisplayName"; Expression={$_.DisplayName}}, ` |
@{Name="EmailAddress"; Expression={$_.Mail}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.Graph.PowerShell.Models.MicrosoftGraphDevice"{ |
if ($Source) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.Id}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={$_.OnPremisesSamAccountName}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.Id}}, ` |
@{Name="SamAccountName"; Expression={$_.OnPremisesSamAccountName}}, ` |
@{Name="DisplayName"; Expression={$_.DisplayName}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.Open.AzureAD.Model.User" { |
if ($Source) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectId}}, ` |
@{Name="SourceUserPrincipalName (Optional)"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetUserPrincipalName (Optional)"; Expression={""}}, ` |
@{Name="TargetSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.ObjectId}}, ` |
@{Name="UserPrincipalName"; Expression={$_.UserPrincipalName}}, ` |
@{Name="SamAccountName"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.Open.AzureAD.Model.Group" { |
if ($Source) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectId}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="TargetObjectId"; Expression={""}}, ` |
@{Name="TargetSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.ObjectId}}, ` |
@{Name="SamAccountName"; Expression={""}}, ` |
@{Name="DisplayName"; Expression={$_.DisplayName}}, ` |
@{Name="EmailAddress"; Expression={$_.Mail}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
"Microsoft.Open.AzureAD.Model.Device" { |
if ($Source) |
{ |
$inputList | |
Select-Object -Property @{Name="SourceObjectId"; Expression={$_.ObjectId}}, ` |
@{Name="SourceSamAccountName (Optional)"; Expression={""}}, ` |
@{Name="Comments (Optional)"; Expression={""}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
else |
{ |
$inputList | |
Select-Object -Property @{Name="ObjectId"; Expression={$_.ObjectId}}, ` |
@{Name="SamAccountName"; Expression={""}}, ` |
@{Name="DisplayName"; Expression={$_.DisplayName}} | |
Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation @saveOperationType |
} |
} |
default { |
Throw "[ERROR]: Type $inputType is not one of the accepted types." |
} |
} |
if ($Append) |
{ |
Write-Host "[INFO]: File '$($outputPath)' appended" |
} |
else |
{ |
Write-Host "[INFO]: File '$($outputPath)' created" |
} |
} |
} |
function ADMapLocalUsers($sourceUsersPath, $targetUsersPath) #Map two user files based on SamAccountName |
{ |
$sourceUsers = Import-Csv -Path $sourceUsersPath -Delimiter "," |
$targetUsers = Import-Csv -Path $targetUsersPath -Delimiter "," |
$mappedUsers = @() |
$nonMappedUsers = @() |
#for each source user, try to find target user via SamAccountName |
$sourceUsers | % { |
$sourceObject = $_ |
$targetMatch = $null |
if ($sourceObject.SamAccountName -ne "") |
{ |
$targetMatch = $targetUsers | Where-Object {$_.SamAccountName -eq $sourceObject.SamAccountName} |
} |
if ($targetMatch) #if found, create match record |
{ |
if ($targetMatch.Count -gt 1) |
{ |
throw "[ERROR]: Target User SamAccountName is not unique '$($sourceObject.SamAccountName)'" |
} |
$mappedUsers += [PSCustomObject]@{ |
SourceObjectId = $sourceObject.ObjectId |
SourceUserPrincipalName = $sourceObject.UserPrincipalName |
SourceSamAccountName = $sourceObject.SamAccountName |
TargetObjectId = $targetMatch.ObjectId |
TargetUserPrincipalName = $targetMatch.UserPrincipalName |
TargetSamAccountName = $targetMatch.SamAccountName |
Comments = "" |
} |
} |
else #if havent found, create record without |
{ |
$nonMappedUsers += [PSCustomObject]@{ |
SourceObjectId = $sourceObject.ObjectId |
SourceUserPrincipalName = $sourceObject.UserPrincipalName |
SourceSamAccountName = $sourceObject.SamAccountName |
TargetObjectId = "" |
TargetUserPrincipalName = "" |
TargetSamAccountName = "" |
Comments = "" |
} |
} |
} |
#save target users which dont have source user match |
$sourceUsersWithSam = $sourceUsers | Where-Object {$_.SamAccountName -ne ""} |
$targetUsersWithoutSourceSam = $targetUsers | Where-Object { $_.SamAccountName -notin $sourceUsersWithSam.SamAccountName} |
$targetUsersWithoutSourceSam | % { |
$nonMappedUsers += [PSCustomObject]@{ |
SourceObjectId = "" |
SourceUserPrincipalName = "" |
SourceSamAccountName = "" |
TargetObjectId = $_.ObjectId |
TargetUserPrincipalName = $_.UserPrincipalName |
TargetSamAccountName = $_.SamAccountName |
Comments = "" |
} |
} |
#save |
$mappedUsers += $nonMappedUsers |
$outputPath = "$PSScriptRoot\user_map_" + [DateTime]::UtcNow.ToString('yyyy_MM_dd_HH_mm_ss') + ".csv" |
$mappedUsers | Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation |
Write-Host "[INFO]: File '$($outputPath)' created" |
} |
function ADMapLocalGroups($sourceGroupsPath, $targetGroupsPath) #Map two group files based on SamAccountName |
{ |
$sourceGroups = Import-Csv -Path $sourceGroupsPath -Delimiter "," |
$targetGroups = Import-Csv -Path $targetGroupsPath -Delimiter "," |
$mappedGroups = @() |
$nonMappedGroups = @() |
#for each source group, try to find target group via SamAccountName |
$sourceGroups | % { |
$sourceObject = $_ |
$targetMatch = $null |
if ($sourceObject.SamAccountName -ne "") |
{ |
$targetMatch = $targetGroups | Where-Object {$_.SamAccountName -eq $sourceObject.SamAccountName} |
} |
if ($targetMatch) #if found, create match record |
{ |
if ($targetMatch.Count -gt 1) |
{ |
throw "Target Group SamAccountName is not unique '$($sourceObject.SamAccountName)'" |
} |
$mappedGroups += [PSCustomObject]@{ |
SourceObjectId = $sourceObject.ObjectId |
SourceSamAccountName = $sourceObject.SamAccountName |
TargetObjectId = $targetMatch.ObjectId |
TargetSamAccountName = $targetMatch.SamAccountName |
Comments = "" |
} |
} |
else #if havent found, create record without |
{ |
$nonMappedGroups += [PSCustomObject]@{ |
SourceObjectId = $sourceObject.ObjectId |
SourceSamAccountName = $sourceObject.SamAccountName |
TargetObjectId = "" |
TargetSamAccountName = "" |
Comments = "" |
} |
} |
} |
#save target groups which dont have source group match |
$sourceGroupsWithSam = $sourceGroups | Where-Object {$_.SamAccountName -ne ""} |
$targetGroupsWithoutSourceSam = $targetGroups | Where-Object { $_.SamAccountName -notin $sourceGroupsWithSam.SamAccountName} |
$targetGroupsWithoutSourceSam | % { |
$nonMappedGroups += [PSCustomObject]@{ |
SourceObjectId = "" |
SourceSamAccountName = "" |
TargetObjectId = $_.ObjectId |
TargetSamAccountName = $_.SamAccountName |
Comments = "" |
} |
} |
#save |
$mappedGroups += $nonMappedGroups |
$outputPath = "$PSScriptRoot\group_map_" + [DateTime]::UtcNow.ToString('yyyy_MM_dd_HH_mm_ss') + ".csv" |
$mappedGroups | Export-Csv -Path $outputPath -Delimiter "," -NoTypeInformation |
Write-Host "[INFO]: File '$($outputPath)' created" |
} |