Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am trying to create a powershell scripts for Remote Desktop Connection Manager using the active directory module.

My first thought was get a list of computers in AD and parse them out into XML format similar to the OU structure that is in AD. I have no problem with that, the below code will work just but not how I wanted.

EG # here is a the array $OUs

Americas/Canada/Canada Computers/Desktops
Americas/Canada/Canada Computers/Laptops
Americas/Canada/Canada Computers/Virtual Computers
Americas/USA/USA Computers/Laptops
Computers
Disabled Accounts
Domain Controllers
EMEA/UK/UK Computers/Desktops
EMEA/UK/UK Computers/Laptops
Outside Sales and Service/Laptops
Servers

I wanted to have the basic XML structured like this

Americas
    Canada
        Canada Computers
            Desktops
            Laptops
            Virtual Computers
    USA
        USA Computers
            Laptops
Computers
Disabled Accounts
Domain Controllers
EMEA
    UK
        UK Computers
            Desktops
            Laptops
Outside Sales and Service
    Laptops
Servers

However if you run the below it does not nest the next string in the array it only restarts the from the beginning and duplicating

Americas
    Canada
        Canada Computers
            Desktops
Americas
    Canada
        Canada Computers
            Laptops
Americas
    Canada
        Canada Computers
            Virtual Computers
Americas
    USA
        USA Computers
            Laptops

RDCMGenerator.ps1

#Importing Microsoft`s PowerShell-module for administering ActiveDirectory 
Import-Module ActiveDirectory 

#Initial variables 
$OUs = @()

$RDCMVer = "2.2"
$userName = "domain\username"
$password = "Hashed Password+"
$Path = "$env:temp\test.xml"

$allComputers = Get-ADComputer -LDAPFilter "(OperatingSystem=*)" -Properties Name,Description,CanonicalName | Sort-Object CanonicalName | select Name,Description,CanonicalName
$allOUObjects = $allComputers | Foreach {"$($_.CanonicalName)"}

Function Initialize-XML{
##<RDCMan schemaVersion="1">
$xmlWriter.WriteStartElement('RDCMan')
    $XmlWriter.WriteAttributeString('schemaVersion', '1')
    $xmlWriter.WriteElementString('version',$RDCMVer)
    $xmlWriter.WriteStartElement('file')
        $xmlWriter.WriteStartElement('properties')
            $xmlWriter.WriteElementString('name',$env:userdomain)
            $xmlWriter.WriteElementString('expanded','true')
            $xmlWriter.WriteElementString('comment','')
            $xmlWriter.WriteStartElement('logonCredentials')
                $XmlWriter.WriteAttributeString('inherit', 'None')
                $xmlWriter.WriteElementString('userName',$userName)
                $xmlWriter.WriteElementString('domain',$env:userdomain)
                $xmlWriter.WriteStartElement('password')
                    $XmlWriter.WriteAttributeString('storeAsClearText', 'false')
                    $XmlWriter.WriteRaw($password)
                $xmlWriter.WriteEndElement()
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('connectionSettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('gatewaySettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('remoteDesktop')
                $XmlWriter.WriteAttributeString('inherit', 'None')
                $xmlWriter.WriteElementString('size','1024 x 768')
                $xmlWriter.WriteElementString('sameSizeAsClientArea','True')
                $xmlWriter.WriteElementString('fullScreen','False')
                $xmlWriter.WriteElementString('colorDepth','32')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('localResources')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('securitySettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('displaySettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
        $xmlWriter.WriteEndElement()    
}
Function Create-Group ($groupName){
#Start Group
        $xmlWriter.WriteStartElement('properties')
            $xmlWriter.WriteElementString('name',$groupName)
            $xmlWriter.WriteElementString('expanded','true')
            $xmlWriter.WriteElementString('comment','')
            $xmlWriter.WriteStartElement('logonCredentials')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('connectionSettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('gatewaySettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('remoteDesktop')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('localResources')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('securitySettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
            $xmlWriter.WriteStartElement('displaySettings')
                $XmlWriter.WriteAttributeString('inherit', 'FromParent')
            $xmlWriter.WriteEndElement()
        $xmlWriter.WriteEndElement()    
}
Function Create-Server ($computerName, $computerDescription) {


    #Start Server
    $xmlWriter.WriteStartElement('server')
        $xmlWriter.WriteElementString('name',$computerName)
        $xmlWriter.WriteElementString('displayName',$computerDescription)
        $xmlWriter.WriteElementString('comment','')
        $xmlWriter.WriteStartElement('logonCredentials')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
        $xmlWriter.WriteStartElement('connectionSettings')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
        $xmlWriter.WriteStartElement('gatewaySettings')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
        $xmlWriter.WriteStartElement('remoteDesktop')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
        $xmlWriter.WriteStartElement('localResources')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
        $xmlWriter.WriteStartElement('securitySettings')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
        $xmlWriter.WriteStartElement('displaySettings')
            $XmlWriter.WriteAttributeString('inherit', 'FromParent')
        $xmlWriter.WriteEndElement()
    $xmlWriter.WriteEndElement()
    #Stop Server
}
Function Close-XML {
    $xmlWriter.WriteEndElement()
$xmlWriter.WriteEndElement()
# finalize the document:
$xmlWriter.Flush()
$xmlWriter.Close()

notepad $path   
}


#Strip out Domain and Computer Name from CanonicalName
foreach($OU in $allOUObjects){
    $newSplit = $OU.split("/")
    $rebildOU = ""
    for($i=1; $i -le ($newSplit.count - 2); $i++){
        $rebildOU += $newSplit[$i] + "/"
    }   
    $OUs += $rebildOU.substring(0,($rebildOU.length - 1))
}

#Remove Duplicate OU's
$OUs = $OUs | select -uniq
#$OUs

# get an XMLTextWriter to create the XML
$XmlWriter = New-Object System.XMl.XmlTextWriter($Path,$UTF8)

# choose a pretty formatting:
$xmlWriter.Formatting = 'Indented'
$xmlWriter.Indentation = 1
$XmlWriter.IndentChar = "`t"

# write the header
$xmlWriter.WriteStartDocument()
#
#   'encoding', 'utf-8' How?
#
# set XSL statements


#Initialize Pre-Defined XML
Initialize-XML

#########################################################
# Start Loop for each OU-Path that has a computer in it
#########################################################
foreach ($OU in $OUs){
    $totalGroupName = ""                            #Create / Reset Total OU-Path Completed

    $OU.split("/") | foreach {                      #Split the OU-Path into individual OU's
        $groupName = "$_"                           #Current OU
        $totalGroupName += $groupName + "/"         #Total OU-Path Completed
        $xmlWriter.WriteStartElement('group')       #Start new XML Group

        Create-Group $groupName                     #Call function to create XML Group

        ################################################
        # Start Loop for each Computer in $allComputers
        ################################################
        foreach($computer in $allComputers){
            $computerOU = $computer.CanonicalName                                       #Set the computers OU-Path
            $OUSplit = $computerOU.split("/")                                           #Create the Split for the OU-Path
            $rebiltOU = ""                                                              #Create / Reset the stripped OU-Path

            for($i=1; $i -le ($OUSplit.count - 2); $i++){                               #Start Loop for OU-Path to strip out the Domain and Computer Name
                $rebiltOU += $OUSplit[$i] + "/"                                         #Rebuild the stripped OU-Path
            }
            if ($rebiltOU -eq $totalGroupName){                                         #Compare the Current OU-Path with the computers stripped OU-Path
                $computerName = $computer.Name                                          #Set the computer name
                $computerDescription = $computerName + " - " + $computer.Description    #Set the computer Description
                Create-Server $computerName $computerDescription                        #Call function to create XML Server
            }
        }
    }
    ###################################################
    # Start Loop to close out XML Groups created above
    ###################################################
    $totalGroupName.split("/") | foreach {  #Split the
        if ($_ -ne "" ){
            $xmlWriter.WriteEndElement()
            #End Group
        }
    }
}               
Close-XML
share|improve this question

migrated from stackoverflow.com Oct 18 '13 at 1:05

This question came from our site for professional and enthusiast programmers.

1  
Quick question: What exactly did you want the script to accomplish? You mentioned the RDC Manager but I don't see what you want it to do, besides output the machines in AD in an XML format? –  BigHomie Oct 16 '13 at 19:58
    
The RDCManager config file is formatted in XML. Please reference microsoft.com/en-ca/download/details.aspx?id=21101 –  CoDeRs Oct 16 '13 at 20:09
1  
Sorry, I forgot all about this tool. Yeah I left it alone a while back for that very reason (I didn't think about exporting from powershell at the time), +1 for the question, I'll take a look unless someone beats me to it. –  BigHomie Oct 16 '13 at 20:19
1  
I'm not sure why this was migrated here. The problem is with your code, this has nothing to do with any function that is native to AD. –  mfinni Oct 18 '13 at 1:46

1 Answer 1

I think that the problem is that you're always creating a new group, inependently if this group already exists or not.

For example, in your code:

   $groupName = "$_"                           #Current OU
   $totalGroupName += $groupName + "/"         #Total OU-Path Completed
   $xmlWriter.WriteStartElement('group')       #Start new XML Group

   Create-Group $groupName                     #Call function to create XML Group

you never checked if the node corresponding to the group $groupName. If your review the Create-Group function, the function itself neither do that check, so you are always creating the group.

The problem here is that the object System.XMl.XmlTextWriter, as far as I know, is intended only for writing without cache, so you should maintain a paralel structure to track group creation or change the way you are generating the XML. I usually use System.XML.XmlDocument instead. I know it's quite manual way of working with XML by my own experience is that is by far more flexible.

Hope this may help!!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.