Help with adding a script method (and quite possibly the code of the method)

This topic contains 3 replies, has 2 voices, and was last updated by  Sam Boutros 3 years ago.

  • Author
    Posts
  • #17768

    stephenmbell
    Participant

    Hello all..

    I am in the middle of writing a script to export my active directory (OU, user, computer, group) to a csv file and import it into another domain for some testing. I have been working on this all day, so I may be in the weeds instead of noticing the wide open field right in front of me – hopefully you can help.

    A simplified version of my export script..

    
    $ou = Get-ADOrganizationalUnit -Filter * | select -Property distinguishedName, name, SamAccountName
    # add some note property members so that all objects have the same properties
    $ou | Add-Member -MemberType NoteProperty -Name UserPrincipalName -Value OU
    $ou | Add-Member -MemberType NoteProperty -Name EmailAddress -Value OU
    $ou | Add-Member -MemberType NoteProperty -Name GroupScope -Value OU
    $ou | Add-Member -MemberType NoteProperty -Name ObjectType -Value OU
    $ou | Export-Csv -Path $objectFile -NoTypeInformation
    
    $user = Get-ADUser -Filter * -Properties * | select -Property distinguishedName, name, SamAccountName, UserPrincipalName, EmailAddress
    # add some note property members so that all objects have the same properties
    $user | Export-Csv -Path $objectFile -NoTypeInformation -Append
    
    $pc = Get-ADComputer -Filter * | select -Property distinguishedName, name, SamAccountName
    # add some note property members so that all objects have the same properties
    $pc | Export-Csv -Path $objectFile -NoTypeInformation -Append
    
    $group = Get-ADGroup -Filter * | select -Property distinguishedName, name, SamAccountName, GroupScope
    # add some note property members so that all objects have the same properties
    $group | Export-Csv -Path $objectFile -NoTypeInformation -Append
    

    The above script exports a to a csv file the OUs, users, groups, and computers.

    Now – for the import –

    I prompt for a new domain name, and then find and replace all necessary instances of the production domain vs the lab domain. Then I import the csv file of all of the objects...

    
    # add a script method to the objects object to count the number of commas in the dn field name
    # this allows me to sort on the number of commas in the DN so I (hopefully) create the OUs in the correct order - for nested OUs
    $objects | Add-Member -MemberType ScriptProperty -Name OULevel -Value {$this.distinguishedName -split "," | Measure-object | select -ExpandProperty Count}
    
    ### - here is where I am stuck ###
    
    $objects | Add-Member -MemberType ScriptMethod -Name BaseDN -Value {$i=$this.distinguishedName.IndexOf(","); $this.distinguishedName.SubString($i, $this.distinguishedName.Length - 1);} 
    

    That doesn't seem to work. I keep getting "Exception Calling BaseDN with "0" arguments: Exception calling "Substring" with 2 arguments.: Index and length must refer to a location within the string"

    What am I doing wrong?

    Thanks in advance
    sb

  • #17769

    Sam Boutros
    Participant

    My initial suggestion is to use XML to store and manipulate complex data types as opposed to CSV, as in using Export-Clixml and Import-Clixml
    I gather the intent is to migrate user, group, computer objects from one forest to another, preserving the group memberships. Any other requirements?
    Is ADMT an option?

  • #17770

    stephenmbell
    Participant

    Thanks for the response. I will check out XML and see if it makes any of my issue different. But – my issue isn't with the CSV. I am able to export it and import it without any issue.

    One of the properties I am exporting is distinguished name. So for example – I export OU=New Computers,DC=mydomain,DC=local. I want to create this OU based on the path – so I want to remove the OU=New Computers, from the DN leaving me with DC=stewartsshops,DC=local for the path parameter to New-ADOrganizationalUnit.

    I have tried using -replace with my splatting. I have tried making a script property and a script method. Something just isn't jiving.

    I am doing this to play around with AD FS for Office 365.

    Thanks again
    sb

  • #17777

    Sam Boutros
    Participant

    The replace method should just work like:

    # Replace all example:
    #
    $SearchFor = "mydomain"
    $ReplaceWith = "stewartsshops"
    [string]$DN = "OU=bl1 1,OU=mydomain,OU=New Computers,DC=mydomain,DC=local."
    #
    [string]$newDN = $DN.Replace($SearchFor,$ReplaceWith)
    Write-Output "   DN == $DN"
    Write-Output "newDN == $newDN"
    

    Output will look like:

           DN => OU=bl1 1,OU=mydomain,OU=New Computers,DC=mydomain,DC=local.
    newDN => OU=bl1 1,OU=stewartsshops,OU=New Computers,DC=stewartsshops,DC=local.
    

    note that all occurrences of the $Searchfor substring have been replaced
    However, if you need to replace substring at a specific level and not thoughout the entire string, Try this:

    # Replace a spcific level example:
    #
    $SearchFor = "mydomain"
    $ReplaceWith = "stewartsshops"
    $Level = 2
    [string]$DN = "OU=bl1 1,OU=mydomain,OU=New Computers,DC=mydomain,DC=local."
    # break out the input string into array to facilitate text manipulation
    [array]$Pieces = $DN.Split(",")
    # Replace the text at the given level only
    $TargetLevel = $Pieces[$Pieces.Length-$Level]
    $newTargetLevel = $TargetLevel.Replace($SearchFor,$ReplaceWith)
    # re-assemble the string back
    [string]$newDN = $null
    foreach ($Piece in $Pieces) {
        if ($Piece -eq $TargetLevel) { $newDN += "$newTargetLevel," } else { $newDN += "$Piece," }
    }
    # remove last comma
    $newDN = $newDN.Substring(0,$newDN.Length -1)
    #
    Write-Output "   DN == $DN"
    Write-Output "newDN == $newDN"
    

    output will look like:

       DN == OU=bl1 1,OU=mydomain,OU=New Computers,DC=mydomain,DC=local.
    newDN == OU=bl1 1,OU=mydomain,OU=New Computers,DC=stewartsshops,DC=local.
    

    here, only substring occurrence at the specified level 2 has been replaced

You must be logged in to reply to this topic.