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" |
} |