如何使用 Powershell 将计算机从 Active Directory 导出到 XML?

如何使用 Powershell 将计算机从 Active Directory 导出到 XML?

我正在尝试使用活动目录模块为远程桌面连接管理器创建一个 powershell 脚本。

我的第一个想法是获取 AD 中的计算机列表,然后将其解析为类似于 AD 中的 OU 结构的 XML 格式。我对此没有问题,下面的代码可以正常工作,但不是我想要的。

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

我希望基本的 XML 结构如下

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

但是如果你运行下面的代码,它不会嵌套数组中的下一个字符串,它只会从头开始重新启动并复制

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

答案1

我认为问题在于你总是在创建一个新组,不管这个组是否已经存在。

例如,在您的代码中:

   $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

您从未检查过节点是否与组 $groupName 相对应。如果您查看 Create-Group 函数,该函数本身不会进行该检查,因此您始终在创建组。

这里的问题是,据我所知,System.XMl.XmlTextWriter 对象仅用于无缓存写入,因此您应该维护一个并行结构来跟踪组创建或更改生成 XML 的方式。我通常使用 System.XML.XmlDocument。根据我的经验,我知道这是处理 XML 的相当手动的方式,而且灵活性要高得多。

希望这能有帮助!

相关内容