Я пытаюсь создать сценарии PowerShell для диспетчера подключений к удаленному рабочему столу, используя модуль активного каталога.
Моей первой мыслью было получить список компьютеров в AD и преобразовать их в формат XML, аналогичный структуре OU в AD. У меня нет проблем с этим, приведенный ниже код будет работать, но не так, как я хотел.
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
Я думаю, что проблема в том, что вы всегда создаете новую группу, независимо от того, существует эта группа уже или нет.
Например, в вашем коде:
$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, по моему собственному опыту, он намного более гибкий.
Надеюсь, это поможет !!