Benutzer mit den meisten Antworten
Rechnerlisten mit angemeldeten Usern

Frage
-
Ich habe mal wieder eine Frage zur Powershell,
ich möchte eine Abfrage machen in der mir die aktiven Rechner mit den Angemeldeten Usern angezeigt werden. Wenn ich eine Liste der Rechner erstelle klappt das auch schon ganz gut. Hierbei stört nur, dass die Liste zwar alle Rechner enthält jedoch nicht immer alle Rechner im Netz sind, und dadurch die Ausführung des Scripts verzögern.
Wenn ich mir über Net View die Liste ziehe bekomme ich den Rechnernamen in dem Format \\ws-116 angezeigt und kann die Zeile dann nicht weiterverarbeiten. Erstelle ich mir eine Liste mit get-adcomputer habe ich alle Rechner aufgelistet, auch die inaktiven, und die sind mir Zeitmäßig einfach im Weg. Kann mir hierbei jemand weiterhelfen?
Gruß
Horst$Anfrage = get-adcomputer -filter 'Name -like "WS-*" ' -Properties * | ? { $_.Enabled -like $true} | select Name
foreach ($rechner in $Anfrage)
{
Write-host "Ich prüfe gerade den $rechner"
if (Test-Connection -ComputerName $rechner -Quiet)
{
Get-WmiObject Win32_ComputerSystem -ComputerName "$rechner" | Select-Object Name,UserName
}
}
Antworten
-
Zur Performance Optimierung empfehle ich dir:
1. Hole nicht alle Properties mit -Properties * das kostet viel Zeit Pro Rechner. Du benutzt am Ende ja nur den Namen!
Am besten ist es wen du nur die Standard Properties holst, indem du den -Properties Parameter weglässt.
Die standard Properites sind Indexiert und können vom Server sehr schnell geliefert werden. Andere Properties muss er erst berechnen das kostet!
Beschäftige dich mal damit, wie das AD intern Arbeitet und wie man Optimierte Abfragen erstellt.Sehr gut währe es auch wenn du die SearchBase auf eine OU (und Sub OUs) einschränkst, im moment durchsuchst du immer das ganze AD.
http://msdn.microsoft.com/en-us/library/ms808539.aspx
Dort:Creating Efficient Queries
2. Man sollte in der PowerShell immer möglichst weit Links in der Pipeline Filtern. Where-Object (Alias Fragezeichen) ist nicht der schnellste Filter! Das Enabled = $True sollte man auch in den AD Filter packen, dann kann der Server dies viel schneller erledigen und er liefert dir nur Rechner die auch enabled sind.
Im Moment bekommst du vom Server alle Rechner zurück und filterst erst dann.
3. Test-Connection Sendet IMMER 4 Pings an einen Rechner wenn er nicht erreichbar ist. Die Zeit die Test-Connection auf einen Ping wartet ist 1 Sekunde (delay). Das sind für jeden Rechner der nicht erreichbar ist: 4 Sekunden.
Hier kannst du Zeit sparen indem du die Ping Anzahl mit dem Parameter -Count auf 1,2 oder 3 reduzierst.
Das Delay lässt sich leider nicht weiter verkürzen da Test-Connection nur Sekunden als Einheit verwendet.
Ich habe für das PowerShell Magazin ein schnelleren Ping entwickelt den du nutzen kannst.
http://www.powershellmagazine.com/2012/10/19/pstip-how-to-speed-up-the-test-connection-command/
Function Test-ConnectionQuietFast { [CmdletBinding()] param( [String]$ComputerName, [int]$Count = 1, [int]$Delay = 500 ) for($I = 1; $I -lt $Count + 1 ; $i++) { Write-Verbose "Ping Computer: $ComputerName, $I try with delay $Delay milliseconds" # Test the connection quiet to the computer with one ping If (Test-Connection -ComputerName $ComputerName -Quiet -Count 1) { # Computer can be contacted, return $True Write-Verbose "Computer: $ComputerName is alive! With $I ping tries and a delay of $Delay milliseconds" return $True } # delay between each pings Start-Sleep -Milliseconds $Delay } # Computer cannot be contacted, return $False Write-Verbose "Computer: $ComputerName cannot be contacted! With $Count ping tries and a delay of $Delay milliseconds" $False } $Anfrage = Get-ADcomputer -Filter {(enabled -eq $False) -and (name -like "WS-*")} | select Name foreach ($Rechner in $Anfrage) { If (Test-ConnectionQuietFast -ComputerName $Rechner -Count 2 -Delay 500 –Verbose) { Get-WmiObject Win32_ComputerSystem -ComputerName "$rechner" | Select-Object Name,UserName } }
Meine PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
Mein deutscher PowerShell Blog
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+ | Deutsches PowerShell Forum (TechNet)- Bearbeitet Peter Kriegel Freitag, 25. Oktober 2013 10:42
- Als Antwort markiert HUCKRI Dienstag, 29. Oktober 2013 10:26
-
Hallo,
ja dann kann es nicht gehen, der 2. Replace schneidet alles rechts vom eigentlichen Computernamen weg, also auch die Beschreibungsspalte, die Leerzeichen zwischen den Spalten usw.Wenn Du nun diesen Teil weg fallen laest wird dein ComputerName erheblich laenger, weil dahinter zahlreiche Space hanengen.
Das kannst Du ganz einfach pruefen in dem dur die mal die Laenge der Computernamen in dem Array ansiehst.
Angenommen der erste Computer in dem Array $Suche ist SRV01 sollte folgender Befhl den Wert 5 anzeigen
$suche[0].length
Wenn du das mit deiner Loesung machst ist der Wert groesser, weil die Space mit genommen werden und somit auch der get-wmiobject einen Computernamen sucht der SRV01[SPACE][SPACE].... usw. sucht, den es aber nicht gibt und genau deshalb kommt der Fehler 0x800706BA .
Wenn dir das Replace nicht gefaellt und dukeine Computer hast, bei denen Beschreibung gefuellt ist kannst Du es auch so machen, um die Space zu entsorgen.
Get-WmiObject Win32_ComputerSystem -ComputerName "$($rechner.Trim())" | Select-Object Name,UserName
Beste Gruesse
brima
Alle Antworten
-
Zur Performance Optimierung empfehle ich dir:
1. Hole nicht alle Properties mit -Properties * das kostet viel Zeit Pro Rechner. Du benutzt am Ende ja nur den Namen!
Am besten ist es wen du nur die Standard Properties holst, indem du den -Properties Parameter weglässt.
Die standard Properites sind Indexiert und können vom Server sehr schnell geliefert werden. Andere Properties muss er erst berechnen das kostet!
Beschäftige dich mal damit, wie das AD intern Arbeitet und wie man Optimierte Abfragen erstellt.Sehr gut währe es auch wenn du die SearchBase auf eine OU (und Sub OUs) einschränkst, im moment durchsuchst du immer das ganze AD.
http://msdn.microsoft.com/en-us/library/ms808539.aspx
Dort:Creating Efficient Queries
2. Man sollte in der PowerShell immer möglichst weit Links in der Pipeline Filtern. Where-Object (Alias Fragezeichen) ist nicht der schnellste Filter! Das Enabled = $True sollte man auch in den AD Filter packen, dann kann der Server dies viel schneller erledigen und er liefert dir nur Rechner die auch enabled sind.
Im Moment bekommst du vom Server alle Rechner zurück und filterst erst dann.
3. Test-Connection Sendet IMMER 4 Pings an einen Rechner wenn er nicht erreichbar ist. Die Zeit die Test-Connection auf einen Ping wartet ist 1 Sekunde (delay). Das sind für jeden Rechner der nicht erreichbar ist: 4 Sekunden.
Hier kannst du Zeit sparen indem du die Ping Anzahl mit dem Parameter -Count auf 1,2 oder 3 reduzierst.
Das Delay lässt sich leider nicht weiter verkürzen da Test-Connection nur Sekunden als Einheit verwendet.
Ich habe für das PowerShell Magazin ein schnelleren Ping entwickelt den du nutzen kannst.
http://www.powershellmagazine.com/2012/10/19/pstip-how-to-speed-up-the-test-connection-command/
Function Test-ConnectionQuietFast { [CmdletBinding()] param( [String]$ComputerName, [int]$Count = 1, [int]$Delay = 500 ) for($I = 1; $I -lt $Count + 1 ; $i++) { Write-Verbose "Ping Computer: $ComputerName, $I try with delay $Delay milliseconds" # Test the connection quiet to the computer with one ping If (Test-Connection -ComputerName $ComputerName -Quiet -Count 1) { # Computer can be contacted, return $True Write-Verbose "Computer: $ComputerName is alive! With $I ping tries and a delay of $Delay milliseconds" return $True } # delay between each pings Start-Sleep -Milliseconds $Delay } # Computer cannot be contacted, return $False Write-Verbose "Computer: $ComputerName cannot be contacted! With $Count ping tries and a delay of $Delay milliseconds" $False } $Anfrage = Get-ADcomputer -Filter {(enabled -eq $False) -and (name -like "WS-*")} | select Name foreach ($Rechner in $Anfrage) { If (Test-ConnectionQuietFast -ComputerName $Rechner -Count 2 -Delay 500 –Verbose) { Get-WmiObject Win32_ComputerSystem -ComputerName "$rechner" | Select-Object Name,UserName } }
Meine PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
Mein deutscher PowerShell Blog
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+ | Deutsches PowerShell Forum (TechNet)- Bearbeitet Peter Kriegel Freitag, 25. Oktober 2013 10:42
- Als Antwort markiert HUCKRI Dienstag, 29. Oktober 2013 10:26
-
Hallo Brima,
wenn ich die Zeile vor dem zweiten -replace kürze ist die Ausgabe so wie ich sie benötige. Baue ich sie in das Script ein gibt er mir in der ersten Zeile den richtigen Rechnernamen zurück, kann aber bei der nächsten Zeile die Variable wohl nicht auslesen. Wenn ich die Variable durch einen Rechnernamen ersetze kann ich auf den Rechner zugreifen.
Gruß
Horst$suche = ((net view) | Select-String "WS-" | select-string '\\\\') -replace '^\\\\','' foreach ($rechner in $suche) { Write-host "Ich prüfe gerade den $rechner" Get-WmiObject Win32_ComputerSystem -ComputerName "$rechner" | Select-Object Name,UserName }
Ich prüfe gerade den WS-168 Get-WmiObject : Der RPC-Server ist nicht verfügbar. (Ausnahme von HRESULT: 0x800706BA) In Zeile:7 Zeichen:1 + Get-WmiObject Win32_ComputerSystem -ComputerName "$rechner" | Select-Object Name ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
- Bearbeitet HUCKRI Montag, 28. Oktober 2013 06:10
- Bearbeitet Alex Pitulice Montag, 28. Oktober 2013 08:14 Space delete
-
Hallo,
ja dann kann es nicht gehen, der 2. Replace schneidet alles rechts vom eigentlichen Computernamen weg, also auch die Beschreibungsspalte, die Leerzeichen zwischen den Spalten usw.Wenn Du nun diesen Teil weg fallen laest wird dein ComputerName erheblich laenger, weil dahinter zahlreiche Space hanengen.
Das kannst Du ganz einfach pruefen in dem dur die mal die Laenge der Computernamen in dem Array ansiehst.
Angenommen der erste Computer in dem Array $Suche ist SRV01 sollte folgender Befhl den Wert 5 anzeigen
$suche[0].length
Wenn du das mit deiner Loesung machst ist der Wert groesser, weil die Space mit genommen werden und somit auch der get-wmiobject einen Computernamen sucht der SRV01[SPACE][SPACE].... usw. sucht, den es aber nicht gibt und genau deshalb kommt der Fehler 0x800706BA .
Wenn dir das Replace nicht gefaellt und dukeine Computer hast, bei denen Beschreibung gefuellt ist kannst Du es auch so machen, um die Space zu entsorgen.
Get-WmiObject Win32_ComputerSystem -ComputerName "$($rechner.Trim())" | Select-Object Name,UserName
Beste Gruesse
brima -
Die PowerShell verarbeitet am liebsten Objekte. Microsoft hat dies so entwickelt weil textverarbeitung (von DOS Befehlen) fehleranfälliger ist.
Deshalb ziehe ich meine Lösung vor, auch wenn sie länger zu tippen ist ;-)Meine PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
Mein deutscher PowerShell Blog
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+ | Deutsches PowerShell Forum (TechNet) -
Hallo,
bei der anderen Lösung schaue ich mir nur die aktuell im Netz befindlichen Rechner an und nicht alle die in der AD als aktiv gekennzeichneten Rechner. Da bei uns im Netz oft nur ein Teil der Rechner an und mit unterschiedlichen Usern besetzt sind möchte ich nur die aktiven Rechner abfragen.
Die Function TestConnectionQuitFast läuft total gut und ich kann die sicher auch noch an anderen Stellen gebrauchen.Gruß
Horst