Como exportar computadores do Active Directory para XML usando o Powershell?

2

Estou tentando criar um script PowerShell para o Remote Desktop Connection Manager usando o módulo de diretório ativo.

Meu primeiro pensamento foi obter uma lista de computadores no AD e analisá-los em formato XML semelhante à estrutura da UO que está no AD. Eu não tenho nenhum problema com isso, o código abaixo funcionará apenas, mas não como eu queria.

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

Eu queria ter o XML básico estruturado assim

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

No entanto, se você executar o código abaixo, ele não aninhará a próxima string na matriz. Ela só reinicia a partir do início e duplica

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
    
por Cody White 16.10.2013 / 21:43

1 resposta

1

Eu acho que o problema é que você está sempre criando um novo grupo, independentemente se esse grupo já existe ou não.

Por exemplo, no seu código:

   $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

você nunca verificou se o nó corresponde ao grupo $ groupName. Se você revisar a função Criar-Grupo, a função em si não fará essa verificação, portanto você estará sempre criando o grupo.

O problema aqui é que o objeto System.XMl.XmlTextWriter, até onde eu sei, é destinado apenas para escrita sem cache, então você deve manter uma estrutura paralela para rastrear a criação do grupo ou mudar a maneira como você está gerando o XML . Eu costumo usar System.XML.XmlDocument em vez disso. Eu sei que é uma maneira bastante manual de trabalhar com XML por minha própria experiência que é de longe mais flexível.

Espero que isso possa ajudar !!

    
por 18.10.2013 / 10:36