none
Проверка вложенности в папках RRS feed

  • Вопрос

  • Привет, всем! У меня такой вопрос: есть папки подразделений и пользователей из AD, мне нужно, чтобы находился последний уровень вложенности и он удалялся, а папки пользователей из этого уровня переходили на уровень выше.

     

    14 декабря 2010 г. 4:18

Ответы

  • $dir = "C:\AD\"
    $strCategory = "organizationalUnit"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.Filter = ("(objectCategory=$strCategory)")
    $colResults = $objSearcher.FindAll()
    
    $domain = $objDomain.distinguishedName -replace "DC=" -replace ",","."
    
    foreach ($objResult in $colResults)
    {
    	$objName= $objResult.Properties
    	$temp = ([ADSI]"$($objName.adspath)").Children | ? {$_.distinguishedName.tostring().startswith("OU=")}
    	foreach ($i in $temp)
    	{
    		if (! (([ADSI]"$($i.adspath)").Children | ? {$_.distinguishedName.tostring().startswith("OU=")}))
    		{
    			$i=$i.distinguishedName -replace ",?(OU=|$($objDomain.distinguishedName)),?","\" -replace "^\\|\\$"
    			[array]::Reverse(($i = $i -split "\\"))
    			[String[]]$del += $i -join "\"
    		}
    	}
    }
    
    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    	if (Test-Path $path)
    	{
    		Move-Item  -Path $path\* -Destination (Split-Path $path-WhatIF
    		Remove-Item -Path $path -Force -Recurse -Whatif
    	}
    }
    

    Если устраивает действия ,то убрать ключ WhatIF
    • Предложено в качестве ответа Angel-Keeper 16 декабря 2010 г. 6:38
    • Помечено в качестве ответа dylanci 21 декабря 2010 г. 6:52
    14 декабря 2010 г. 9:59
    Отвечающий
  •  

     dir | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}},FullName
    

     

    Привет, посмотри в чем моя ошибка, я попытался использовать уровни вложенности для того, чтобы скрипт перемещал пользователей только таких, которые находятся во вложенных папках 3 и более уровней, а не каждого уровня.

     

    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    
     if ((dir $path | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}}) -ge 7)
     {
     
     if (Test-Path $path)
    	 {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	 }
     }
    }
     Он выдает число вложенности папки, но но не перемещает - пишет: "Не удается сравнить "@{Depth=9}" с "7", так как объекты не принадлежат к одному типу, ли

     

    бо объект "@{Depth=9}" не реализует "IComparable"." 

     

    Пытался перевести в int, но без результатно, пишет что путь не найден

    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    
     if ($path.split("\").count -ge 7)
     {
     
     if (Test-Path $path)
    	 {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	 }
     }
    }

    • Помечено в качестве ответа dylanci 21 декабря 2010 г. 6:52
    17 декабря 2010 г. 14:02
    Отвечающий

Все ответы

  • $dir = "C:\AD\"
    $strCategory = "organizationalUnit"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.Filter = ("(objectCategory=$strCategory)")
    $colResults = $objSearcher.FindAll()
    
    $domain = $objDomain.distinguishedName -replace "DC=" -replace ",","."
    
    foreach ($objResult in $colResults)
    {
    	$objName= $objResult.Properties
    	$temp = ([ADSI]"$($objName.adspath)").Children | ? {$_.distinguishedName.tostring().startswith("OU=")}
    	foreach ($i in $temp)
    	{
    		if (! (([ADSI]"$($i.adspath)").Children | ? {$_.distinguishedName.tostring().startswith("OU=")}))
    		{
    			$i=$i.distinguishedName -replace ",?(OU=|$($objDomain.distinguishedName)),?","\" -replace "^\\|\\$"
    			[array]::Reverse(($i = $i -split "\\"))
    			[String[]]$del += $i -join "\"
    		}
    	}
    }
    
    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    	if (Test-Path $path)
    	{
    		Move-Item  -Path $path\* -Destination (Split-Path $path-WhatIF
    		Remove-Item -Path $path -Force -Recurse -Whatif
    	}
    }
    

    Если устраивает действия ,то убрать ключ WhatIF
    • Предложено в качестве ответа Angel-Keeper 16 декабря 2010 г. 6:38
    • Помечено в качестве ответа dylanci 21 декабря 2010 г. 6:52
    14 декабря 2010 г. 9:59
    Отвечающий
  • Он выполняет скрипт, даже пишет, что перемещает и удаляет, но на самом деле все осталось на прежнем месте  после того, как они были созданы.

     

    Он выдает ошибку: "Test-Path : Путь содержит недопустимые знаки", я думаю, что это из-за того, что в $path есть пробелы, пробовал ставить кавычки, но без результатно.

     

    15 декабря 2010 г. 13:37
  • Он выполняет скрипт, даже пишет, что перемещает и удаляет, но на самом деле все осталось на прежнем месте  после того, как они были созданы.

     

    Он выдает ошибку: "Test-Path : Путь содержит недопустимые знаки", я думаю, что это из-за того, что в $path есть пробелы, пробовал ставить кавычки, но без результатно.

     

    Я же написал выше,что убрать -WhatIF,если требуются действия.

    Move-Item  -Path $path\* -Destination (Split-Path $path) 
    Remove-Item -Path $path -Force -Recurse 

    Покажите проблемный путь.


    15 декабря 2010 г. 14:06
    Отвечающий
  •  

    Скажите, как можно помечать или считать уровни вложенности папок при помощи test-path, get-childitem. Я пытался сделать при помощи

    $a = get-childitem 

    $a.count, а если все это в цикл поместить, то он считает общее количесвто  папок а не уровни вложености, да плюсом у меня не получается вернуться назад в цикле, если нет больше вложенных папок.

    16 декабря 2010 г. 7:16
  •  

    Скажите, как можно помечать или считать уровни вложенности папок при помощи test-path, get-childitem. Я пытался сделать при помощи

    $a = get-childitem 

    $a.count, а если все это в цикл поместить, то он считает общее количесвто  папок а не уровни вложености, да плюсом у меня не получается вернуться назад в цикле, если нет больше вложенных папок.

    Можно так:

     

    PS > pwd
    
    Path
    ----
    C:\Users\Test
    
    PS > dir | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}},FullName
    
    
    Depth FullName
    ----- --------
      3 C:\Users\Test\.VirtualBox
      3 C:\Users\Test\AppVerifierLogs
      3 C:\Users\Test\Contacts
      3 C:\Users\Test\Desktop
      3 C:\Users\Test\Documents
      3 C:\Users\Test\Downloads
      3 C:\Users\Test\Favorites
      3 C:\Users\Test\Links
      3 C:\Users\Test\Music
      3 C:\Users\Test\Pictures

     

    16 декабря 2010 г. 12:29
    Отвечающий
  •  

     dir | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}},FullName
    

     

    Привет, посмотри в чем моя ошибка, я попытался использовать уровни вложенности для того, чтобы скрипт перемещал пользователей только таких, которые находятся во вложенных папках 3 и более уровней, а не каждого уровня.

    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    
      if ((dir $path | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}}) -ge 7)
      {
      
        if (Test-Path $path)
    	  {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	  }
      }
    }
     Он выдает число вложенности папки, но но не перемещает - пишет: "Не удается сравнить "@{Depth=9}" с "7", так как объекты не принадлежат к одному типу, ли

    бо объект "@{Depth=9}" не реализует "IComparable"." 

     

    Пытался перевести в int, но без результатно, пишет что путь не найден

    17 декабря 2010 г. 13:04
  •  

     dir | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}},FullName
    

     

    Привет, посмотри в чем моя ошибка, я попытался использовать уровни вложенности для того, чтобы скрипт перемещал пользователей только таких, которые находятся во вложенных папках 3 и более уровней, а не каждого уровня.

     

    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    
     if ((dir $path | ? {$_.psiscontainer} | select @{n="Depth";e= { ($_.fullname -split "\\" | Measure-Object).count-1}}) -ge 7)
     {
     
     if (Test-Path $path)
    	 {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	 }
     }
    }
     Он выдает число вложенности папки, но но не перемещает - пишет: "Не удается сравнить "@{Depth=9}" с "7", так как объекты не принадлежат к одному типу, ли

     

    бо объект "@{Depth=9}" не реализует "IComparable"." 

     

    Пытался перевести в int, но без результатно, пишет что путь не найден

    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    
     if ($path.split("\").count -ge 7)
     {
     
     if (Test-Path $path)
    	 {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	 }
     }
    }

    • Помечено в качестве ответа dylanci 21 декабря 2010 г. 6:52
    17 декабря 2010 г. 14:02
    Отвечающий
  • Большое спасибо!

    Вот итоговый скрипт для создания и удаление нижних уровней вложенности (я знаю, что он составлен не "по-человечески"):

    #Создание папок для пользователей в подразделениях
    $dir = "D:\ADf\"
    $strCategory = "user"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry 
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    #$objSearcher.SearchRoot = 'trsvpu.ru/MAIP/Пользователи/Сотрудники'
    $objSearcher.Filter = ("(objectCategory=$strCategory)")
    $colResults = $objSearcher.FindAll()
    
    $domain = $objDomain.distinguishedName -replace "DC=" -replace ",","."
    
    foreach ($objResult in $colResults)
    {
    	$objName= $objResult.Properties
    	$temp = $objName.distinguishedname -replace ",?(CN=|OU=|$($objDomain.distinguishedName)),?","\" -replace "^\\|\\$"
    	[array]::Reverse(($temp = $temp -split "\\"))
    	$temp[-1] = $temp[-1] -replace "\."," "
    	New-Item -Path ($dir + $domain + "\" + ($temp -join "\")) -ItemType directory -ErrorAction SilentlyContinue -Force 
    }
    
    #Перемещение папки сотрудники в каталог и удаление domain_name\MAIP\Пользователи
    move-item -path D:\ADf\domain_name.ru\MAIP\Пользователи\Сотрудники -destination D:\ADf
    Remove-Item -Path D:\ADf\domain_name.ru -Force -Recurse
    
    
    #Удаление нижних уровней папок вложенности
    $dir = "D:\ADf\"
    $strCategory = "organizationalUnit"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.Filter = ("(objectCategory=$strCategory)")
    $colResults = $objSearcher.FindAll()
    
    $domain = $objDomain.distinguishedName -replace "DC=" -replace ",","."
    
    foreach ($objResult in $colResults)
    {
    	$objName= $objResult.Properties
    	$temp = ([ADSI]"$($objName.adspath)").Children | ? {$_.distinguishedName.tostring().startswith("OU=")}
    	foreach ($i in $temp)
    	{
    		if (! (([ADSI]"$($i.adspath)").Children | ? {$_.distinguishedName.tostring().startswith("OU=")}))
    		{
    			$i=$i.distinguishedName -replace ",?(OU=|$($objDomain.distinguishedName)),?","\" -replace "^\\|\\$"
    			[array]::Reverse(($i = $i -split "\\"))
    			[String[]]$del += $i -join "\"
    		}
    	}
    }
    
    foreach ($a in $del)
    {
    	$path = $dir + $domain + "\" + $a 
    
     if ($path.split("\").count -ge 3)
     {
     
         if (Test-Path $path)
    	 {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	 }
     }
     elseif ($path.split("\").count -ge 2)
     {
    	 if (Test-Path $path)
    	 {
    		 Move-Item -Path $path\* -Destination (Split-Path $path)
    		 Remove-Item -Path $path -Force -Recurse
    	 }
     }

    21 декабря 2010 г. 6:52
  • Скажите, как можно совместить созданный скрипт (скрипт по созданию папок пользователей и удаления нижних уровней вложенности) со следующим скриптом, который разбивает "Иванов Иван Иванович" на "Иванов И.И.":

    $a += gc D:\res3.txt | foreach {$arr = $_.split(" ")
    $user = $arr[0] + " " + $arr[1].substring(0,1) + "." + $arr[2].substring(0,1) + "."
    Write-Host $user
    }
    

    в файл res3.txt записывал имена всех юзеров следующим образом:

    $st = Get-ADUser -Filter 'name -like "*"'| 
     foreach {write-host $_.Name;
     #$x = $_.DistinguishedName.split(",")
     foreach ($ou in $x)
     {
      #Write-Host $ou
         foreach ($ou in $x)
         {
          $x | out-file D:\res3.txt;
         }
     }

    21 декабря 2010 г. 8:30