derpue
Goto Top

Powershell script läuft ohne Fehler, erzeugt aber kein Ausgabe

Hallo zusammen,

vielleicht kann mir jemand von euch weiterhelfen.
Ich habe hier ein Powershell Script, welches die AD durchsucht und mit mir die Größen der Homefolders in eine Exel tabelle speichern soll. Dazu habe ich einen Filter eingestellt der in der AD nach Abteilung und DFS-Root sucht
Nach ersten Problemchen, läuft das Script jetzt durch. Es werden exakt die Anzahl von ergebnissen dargestellt wie Anwender in der Abteilung mit dem genutzten DFS-Root existieren.
Es wird auch eine Exel Tabelle erzeugt. Diese ist jedoch Leer und beinhalten lediglich die Überschriften und am Ende ein Ergebnisfeld. Ich hoffe jemand hat heir einen Denkanstoss für mich, damit ich weiterkomme. Vielen Dank im voraus ;)
Hier das Script
import-module ActiveDirectory

$OU = "dc=meine,dc=firma"  

$objExcel = New-Object -ComObject "Excel.Application"  
$objExcel.Visible = $false
$doc = $objExcel.Workbooks.Add()
$lo = $doc.Worksheets.Item(1).ListObjects.Add(1,$objExcel.Range("A1:B1"))  
$lo.HeaderRowRange.Cells.Item(1,1).value2 = "Name"  
$lo.HeaderRowRange.Cells.Item(1,2).value2 = "Ordnergröße"  
$lo.ShowTotals = $True
$lo.ListColumns.Item(2).TotalsCalculation = 1

$ObjFilter = "(&(objectCategory=User)(objectCategory=Person))"   
$objSearch = [adsisearcher]'(&(objectCategory=User)(objectCategory=Person))'   
$objSearch.PageSize = 15000 
$objSearch.Filter = $ObjFilter 
$objSearch.SearchRoot = "LDAP://$OU"   
$AllObj = GET-QADUser -LdapFilter "(physicalDeliveryOfficeName=Abteilung-123*)(homedirectory=*dfs-123*)" -SearchRoot 'DC=meine,DC=firma" | Select-Object Displayname, HomeDirectory   
foreach ($Obj in $AllObj) { 
    $objItem = $Obj.Properties 
    $displayName = $objItem.displayname
    $profilePath = $objItem.profilepath
    if ($profilePath){
	   $size1 = [System.Math]::Round((dir "$profilePath" -Recurse | Measure-Object -Property length -Sum).Sum / (1024 * 1024),2)  
    }else{
	   $size1 = ""  
    }
    $lo.ListRows.Add()
    $lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,1).value2 = $displayname
    $lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,2).value2 = $size1.Replace(",",".")  
}

$objExcel.Visible = $true


Vielen Dank im voraus.

Viele Grüße
DerPue

Content-ID: 212421

Url: https://administrator.de/contentid/212421

Ausgedruckt am: 22.11.2024 um 15:11 Uhr

DerPue
DerPue 25.07.2013 um 08:19:35 Uhr
Goto Top
_Nachtrag_
Ich habe die "ActiveRoles Managaement Shell for Active Directory x64" installiert, für die Abfrage in Zeile 19.
colinardo
colinardo 25.07.2013 aktualisiert um 11:35:19 Uhr
Goto Top
Hallo DerPue,
das Script kenne ich doch irgend woher face-wink
warum baust du den LDAP-Filter nicht direkt an der Stelle ein die dafür gedacht ist:
$ObjFilter = "(&(objectCategory=User)(objectCategory=Person)(physicalDeliveryOfficeName=Abteilung-123*)(homedirectory=*dfs-123*))"

Das Get-QADUser liefert natürlich für den Code in der Schleife nicht den richtigen Objekttyp, deswegen wird auch kein Inhalt in das Excel-File geschrieben.
Mach es mal so:
import-module ActiveDirectory

$OU = "dc=meine,dc=firma"  

$objExcel = New-Object -ComObject "Excel.Application"  
$objExcel.Visible = $false
$doc = $objExcel.Workbooks.Add()
$lo = $doc.Worksheets.Item(1).ListObjects.Add(1,$objExcel.Range("A1:B1"))  
$lo.HeaderRowRange.Cells.Item(1,1).value2 = "Name"  
$lo.HeaderRowRange.Cells.Item(1,2).value2 = "Ordnergröße"  
$lo.ShowTotals = $True
$lo.ListColumns.Item(2).TotalsCalculation = 1

$ObjFilter = "(&(objectCategory=User)(objectCategory=Person)(physicalDeliveryOfficeName=Abteilung-123*)(homedirectory=*dfs-123*))"   
$objSearch =New-Object System.DirectoryServices.DirectorySearcher
$objSearch.PageSize = 15000 
$objSearch.Filter = $ObjFilter 
$objSearch.SearchRoot = "LDAP://$OU"   
$AllObj = $objSearch.FindAll()
foreach ($Obj in $AllObj) { 
    $objItem = $Obj.Properties
    $displayName = ""  
    $displayName = $objItem.displayname
    $profilePath = $objItem.profilepath
    if ($profilePath){
	   $size1 = [System.Math]::Round((dir "$profilePath" -Recurse | Measure-Object -Property length -Sum).Sum / (1024 * 1024),2)  
    }else{
	   $size1 = ""  
    }
    $lo.ListRows.Add()
    $lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,1).value2 = $displayname
    $lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,2).value2 = $size1.Replace(",",".")  
}

$objExcel.Visible = $true

Grüße Uwe
Gelöste Beitrage bitte auch als solche markieren.Danke.
DerPue
DerPue 25.07.2013 um 10:29:09 Uhr
Goto Top
Hallo Uwe,

Danke für Deine Antwort.
Ja genau, das Script sollte bekannt sein ;) Bin seinerzeit an einer Stelle nicht weitergekommen, da nun aber die Anforderung besteht, nach Abteilungen und Homedirectorys zu suchen, hab ich´s nochmal ausgekramt ^^
Den Filter hatte ich bereits an diser Stelle und erhalte bei jeder Antwort diese Fehlermeldung:
 
Application : Microsoft.Office.Interop.Excel.ApplicationClass
Creator     : 1480803660
Parent      : System.__ComObject
Index       : 25
InvalidData : 
Range       : System.__ComObject

Ausnahme beim Festlegen von "Value2": "Exception from HRESULT: 0x800A03EC"  
In Zeile:34 Zeichen:5
+     $lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,1).value2 = $displa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) , SetValueInvocationException
    + FullyQualifiedErrorId : CatchFromBaseAdapterSetValueTI

vielleicht siehst Du ja noch irgendwo einen Fehler?


Viele Grüße
DerPue
colinardo
colinardo 25.07.2013 um 10:33:53 Uhr
Goto Top
nehme beim Füllen der Excel Zellen mal folgende Eigenschaft: .value
$lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,1).value = $displayname 
$lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,2).value = $size1.Replace(",",".")
DerPue
DerPue 25.07.2013 um 10:42:22 Uhr
Goto Top
Das führt leider nur zu einem anderen Fehler
Ausnahme beim Festlegen von "value": "Die Value-Eigenschaft für das PSMemberInfo-Objekt vom Typ "System.Management.Automation.PSParameterizedProperty" kann nicht   
festgelegt werden."  
In Zeile:30 Zeichen:5
+     $lo.ListRows.Item($lo.ListRows.Count).Range.Cells.Item(1,1).value = $display ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) , SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting
DerPue
DerPue 25.07.2013 um 15:06:42 Uhr
Goto Top
Da ich an dieser Stelle irgendwie nicht weiter komme, hab ich mir was anderes überlegt. Ich nehme folgendes Script
$ObjFilter = "(&(objectCategory=person)(objectCategory=User)(physicalDeliveryOfficeName=Abteilung123*)(homedirectory=*dfs-123*))"   
    $objSearch = New-Object System.DirectoryServices.DirectorySearcher 
    $objSearch.PageSize = 15000 
    $objSearch.Filter = $ObjFilter  
    $objSearch.SearchRoot = "LDAP://dc=meine,dc=firma"   
    $AllObj = $objSearch.FindAll() 
    foreach ($Obj in $AllObj) 
           {
            $objItemS = $Obj.Properties
            $objItemS.homedirectory | out-file "c:\scripts\output.txt" -append  
           }
    get-content "C:\Scripts\output.txt" | get-childItem -recurse  
Soweit, sogut ;)
Die Verzeichnisse werden mir nun alle angezeigt. Wenn ich nun allerdings versuche mit die Größen anzeigen zu lassen bzw. diese in eine csv zu speichern mit folgender Ergänzung in Zeile 12:
get-content "C:\Scripts\output.txt" | get-childItem -recurse | measure-object -property length -sum >> "C:\temp2\verzeichnisse.csv"  
erhalte ich die Meldung, dass der Name zu lang sei. Ich darf nur max. 260 Zeichen nutzen. Aber wieso bekomme ich die Dateien und Verzeichnisse ohne dass ich "measure-object" in die Pipe nehme angezeigt?
Jemand eine Idee?
colinardo
colinardo 25.07.2013 aktualisiert um 15:21:07 Uhr
Goto Top
Zitat von @DerPue:
erhalte ich die Meldung, dass der Name zu lang sei. Ich darf nur max. 260 Zeichen nutzen.
Da liegt wahrscheinlich der Hund in der Pfanne begraben, Pfade dürfen in Windows maximal 255 Zeichen lang sein.
Das dürfte auch im obigen Script die Fehlerursache sein, denn hier läuft mein Script soweit einwandfrei.
DerPue
DerPue 25.07.2013 um 15:36:42 Uhr
Goto Top
*grummel*
;)
Ja das mit der Zeichenbegrenzung ist mir leider bekannt....^^
Merkwürdig ist halt, dass mit dem Befehl
get-content "C:\Scripts\output.txt" | get-childItem -recurse  
die Dateien trotzdem alle angezeigt werden.
Sowie, dass mit dem Script hier:
 set-Location c:\
add-PSSnapin  quest.activeroles.admanagement

$AllObj = GET-QADUser -LdapFilter '(&(physicalDeliveryOfficeName=Abteilung123**)(homedirectory=*dfs-012*))' -SearchRoot 'DC=meine,DC=Firma' | Select-Object Displayname, HomeDirectory  

foreach ($Obj in $AllObj) 
      {
      $fs = New-Object -comobject Scripting.FileSystemObject
      $tempSize = $fs.GetFolder($Obj.homedirectory).size/1024/1024
      $tempSize = ‘{0:N}’ -f [double]$tempSize
      Write-Host "$Obj.Displayname" + “$tempSize MB”  
      } 
Auch die Ausgabe der Directorys und Größen angegeben wird.... hier hab ich leider nciht geschafft, mir das ganze in eine csv o.ä. ausgeben zu lassen.
Vielleicht kann man ja daran anknüpfen, sofern Du einen Denkanstoß für mich hast :D
Vielen Dank auf jeden Fall schonmal im voraus für Deine in meine Frage investierte Zeit.

viele Grüße
colinardo
colinardo 25.07.2013 aktualisiert um 16:11:10 Uhr
Goto Top
Wenn du es in eine CSV-Datei schreiben willst kannst du das so machen:
$array = @()

$ObjFilter = "(&(objectCategory=person)(objectCategory=User)(physicalDeliveryOfficeName=Abteilung123*)(homedirectory=*dfs-123*))"   
    $objSearch = New-Object System.DirectoryServices.DirectorySearcher 
    $objSearch.PageSize = 15000 
    $objSearch.Filter = $ObjFilter  
    $objSearch.SearchRoot = "LDAP://dc=meine,dc=firma"   
    $AllObj = $objSearch.FindAll() 
    foreach ($Obj in $AllObj) 
    {
            $objItemS = $Obj.Properties
            $dir = $objItemS.homedirectory
            $size =[System.Math]::Round((dir $dir -Recurse | Measure-Object -Property length -Sum).Sum / (1024 * 1024),2)
            $entry = @{Folder=$dir;Size=$size}
            $array += New-Object PSObject -Property $entry
   }
   $array | export-csv "C:\Scripte\test.csv" -NoTypeInformation  
DerPue
DerPue 26.07.2013 aktualisiert um 07:46:54 Uhr
Goto Top
Leider gibts auch hier den Fehler, dass zuviele Zeichen vorhanden sind...

Dieses hier läuft nun:
 set-Location c:\
add-PSSnapin  quest.activeroles.admanagement

$AllObj = GET-QADUser -LdapFilter '(physicalDeliveryOfficeName=Abteilung123*)(homedirectory=*dfs-123*)' -SearchRoot 'DC=meine,DC=firma' | Select-Object Displayname, HomeDirectory  

foreach ($Obj in $AllObj) 
      {
      $fs = New-Object -comobject Scripting.FileSystemObject
      $tempSize = $fs.GetFolder($Obj.homedirectory).size/1024/1024
      $tempSize = ‘{0:N3}’ -f [double]$tempSize
      $Obj.Displayname + "$tempSize MB" | out-file -filepath "C:\temp2\test.csv" -append  
      } 

hier ist jetzt lediglich das Problem, dass bei einigen Verzeichnissen die Fehlermeldung erscheint,
code>
Der Wert "1.814,275" kann nicht in den Typ "System.Double" konvertiert werden. Fehler: "Input string was not in a correct format."
In Zeile:22 Zeichen:7
+ $tempSize = ‘{0:N3}’ -f [double]$tempSize


unschön ist auch dass nun der Name und die Verzeichnisgröße direkt nebeneinander stehen und räumlich nicht getrennt werden.
Auch die Umwandlung in GB will nicht so recht funktionieren face-sad
colinardo
colinardo 26.07.2013 um 07:49:49 Uhr
Goto Top
Für überlange Pfadnamen gibt es eine Powershell Function die auf einem Workaround mit Robocopy basiert:
http://gallery.technet.microsoft.com/scriptcenter/Function-to-get-file- ...
DerPue
DerPue 30.07.2013 um 12:50:12 Uhr
Goto Top
Hello again,
heute bin ich mal wieder dazu gekommen, mich mit dem Script ein wenig zu befassen.
Bin jetzt zumindest soweit, dass ich mir die Verzeichnispfade in eine csv schreiben lasse und danach die einzelnen Einträge abarbeiten lasse.
Hier mal das Script:
#Erstellen einer Verzeichnisliste mit Userhome
$ObjFilter = "(&(objectCategory=person)(objectCategory=User)(physicalDeliveryOfficeName=Abteilung123*)(homedirectory=*dfs-123*))"   
    $objSearch = New-Object System.DirectoryServices.DirectorySearcher 
    $objSearch.PageSize = 15000 
    $objSearch.Filter = $ObjFilter  
    $objSearch.SearchRoot = "LDAP://dc=meine,dc=firma"   
    $AllObj = $objSearch.FindAll() 
    foreach ($Obj in $AllObj) 
           {
            $objItemS = $Obj.Properties
            $objItemS.homedirectory | out-file "c:\scripts\output.csv" -append  
           } 
#Liste einlesen und Größe berechnen 
$startfolder=get-content c:\scripts\output.csv 
 
$colItems = (Get-ChildItem $startFolder -recurse | Measure-Object -property length -sum)
 "$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB" | out-file C:\Scripts\test.csv  
leider scheiter ich noch an der Pfadlänge, hier habe ich es auch net geschafft den Link, welchen colinardo freundlicherweise gepostet hat einzubauen. face-sad
Unschön ist auch, dass nachdem das Script durchgelaufen ist, alle Verzeichnispfade in einer Zeile geschrieben werden und am Ende die Größe angegeben wird.

Vielleicht hat jemand noch eine Idee? Würde mich freuen....

Vieel Grüße
DerPue
DerPue
DerPue 13.08.2013 um 09:06:50 Uhr
Goto Top
Wir haben es nun wie folgt gelöst.... direkt auf dem Fileserver ausgeführt...

Import-Module ActiveDirectory

$date = Get-Date -uformat "%Y-%m-%d"  
$ExportFile = "C:\Export\Userhomes $Date.txt"  
#$USRHs = @$USRHs = @("E:\HOME") 

$IDsVol = @()
foreach ($USRH in $USRHs) {
	$IDs = Get-ChildItem $USRH
	foreach ($ID in $IDs) {
		Write-Host "Lese Userhome: " $ID.Name  
		$dept = $Null
		$dept = (Get-ADUser $ID.Name -Properties PhysicalDeliveryOfficeName).PhysicalDeliveryOfficeName
		$Path = $USRH + "\" + $ID.Name  
		$SUM = Get-ChildItem $Path -recurse | Measure-Object -property length -sum
		$GiB = $SUM.sum / 1024 / 1024 / 1024
		$IDsVol += New-Object psobject -Property @{ID=$ID.Name; GiB=[math]::Round($GiB,3); Department=$dept.substring(0,$dept.indexof(" ")); USRH=$USRH}  
		cls
		$IDsVol | ft ID, GiB, Department, USRH -AutoSize
	}
}

$IDsVol | Sort Department | Select-Object ID, GiB, Department, USRH | Export-Csv $ExportFile -Delimiter ";"  
colinardo
colinardo 13.08.2013 um 09:11:51 Uhr
Goto Top
Gelöste Beitrage bitte auch als solche markieren.face-wink Danke.