Dein Powershell erzeugt "computers.txt", nicht "AllActivPC.txt"
Getzabba!
Jepp
Dein Powershell erzeugt "computers.txt", nicht "AllActivPC.txt"
Getzabba!
Jepp
Gut ich merke schon, sind nicht viele Powershell Freunde hier, is nur schade da ich halt noch einige nützliche PS Scripte habe, und warum das Rad neu erfinden. Ok dann versuchen wir es halt wie emfohlen, bin ja noch halbwegs formbar, trotz meines hohen Alters. So Frage: wie kann ich aus dem AD die Beschreibung spalte auslsen, ich bekomme da immer nur Array[1] zu lesen.
#include <ADfunctions.au3>
#include <Array.au3>
; Globale Variable für Computer
Global $aComputers
$sOU = $strDNSDomain
; AD-Abfrage, um nur Computer zu holen, deren Name mit "A" oder "N" beginnt
_ADGetObjectsInOU($aComputers, $sOU, "(&(objectclass=computer)(|(name=A*)(name=N*)))", 2, "name,operatingSystem,description")
; Ausgabe der gefundenen Computer
_ArrayDisplay($aComputers)
Alles anzeigen
lg und schönen Abend noch
Ich sehe, dass Du auf die alte AD UDF (ADfunctions, Stand: Juli 2009) gewechselt hast.
Gibt es einen speziellen Grund dafür?
Die AD UDF ist aktualisiert (Stand: August 2022) mit einer Hilfe-Datei, Beispielen sowie verbesserter Fehlerbehandlung. Was in diesem Fall die Fehlersuche seeeehr vereinfacht.
Ich würde empfehlen, bei der AD UDF zu bleiben.
@casi4712 schau mal bei Water in die Signatur unter meine Werke, da findest du die aktuelle AD UDF.
hier mal ein Beispiel.
Um die Beschreibung vom Computer herauszubekommen muss das $ an gehangen werden.
_AD_GetObjectAttribute($aObjects[$i][0] & "$", "description")
#include <D:\scripte\AD_1.6.2.0_Functions\AD.au3> ;AD.au3 von Water -> Pfad muss angepasst werden
#include <Array.au3>
local $serverArray [1]
local $clientsArray [1][2] ;2D Array
_AD_Open()
$sOU = "OU=eureOU,DC=domain,DC=int" ;muss angepasst werden
$aObjects = _AD_GetObjectsInOU($sOU, "(objectclass=computer)", 2, "name,operatingSystem")
_ArrayDisplay($aObjects) ; alle Computer
If @error > 0 Then
MsgBox(64, "", "Nichts gefunden")
Else
For $i = 1 To $aObjects[0][0]
$fill = ""
;MsgBox(0,"", $aObjects[$i][1])
$server = StringLeft ($aObjects[$i][1],14)
$clients = StringLeft ($aObjects[$i][1],10)
;MsgBox(0,"",$server)
IF $server = "Windows Server" Then
;MsgBox(0,"",$aObjects[$i][0])
_ArrayAdd($serverArray, $aObjects[$i][0])
EndIf
IF $clients = "Windows 10" Or $clients = "Windows 11" Then
$description = _AD_GetObjectAttribute($aObjects[$i][0] & "$", "description")
;MsgBox(0,$aObjects[$i][0],$description)
$fill = $aObjects[$i][0] & "|" & $description
_ArrayAdd($clientsArray, $fill)
EndIf
Next
_ArrayDisplay($serverArray) ; Server Array
_ArrayDisplay($clientsArray) ; Clients Array
EndIf
_AD_Close()
Alles anzeigen
oder um das mit deinem Script zu machen. die Description muss natürlich auch im AD gesetzt sein.
_AD_Open()
; Globale Variable für Computer
Global $aComputers
;$sOU = $strDNSDomain
$sOU = "OU=OU1234,DC=Domain,DC=int" ;muss angepasst werden
; AD-Abfrage, um nur Computer zu holen, deren Name mit "A" oder "N" beginnt
$aComputers = _AD_GetObjectsInOU($sOU, "(&(objectclass=computer)(|(name=F*)(name=N*)))", 2, "name,operatingSystem,description")
; Ausgabe der gefundenen Computer
_ArrayDisplay($aComputers)
_AD_Close()
Alles anzeigen
oj sorry stimmt, kA warum ich jett das genommen hatte, dachte wär das selbe, wie würde das denn mit der neuen aussehen,? Und kannd as die Bezeichnung aus dem AD auslesen?
lg und schönes WE
Auf Basis der ADfunctions UDF habe ich die AD UDF entwickelt. Die Syntax ist sehr ähnlich.
Das obige Beispiel von gmmg sollte das von Dir gewünschte Ergebnis (inkl. Description) liefern.
okidoki werde mich da mal sachschlau machen, recht herzlichen dank.
lg und schönes Wocheende
So ich habs jetzt noch mal vereinfacht geschrieben, das temporäre PS funktioniert und gibt eine Liste der erreichbaren PCs aus. Leider schaffe ich es nicht dass die in das entsprechende txt file geschrieben werden, was ,mache ich falsch?
so sieht das Ganze aus:
#include <FileConstants.au3>
#include <Array.au3>
#include <FileConstants.au3>
#include <Array.au3>
Local $FileName = "AllActivPC.txt"
Local $TempDir = @TempDir ; Benutzer-Temp-Verzeichnis
Local $ScriptDir = @ScriptDir & "\scripts" ; Scripts-Verzeichnis
; PowerShell-Skript als Zeichenkette mit zusätzlichen Write-Output-Anweisungen
Local $sScript = _
'$ComputersA = Get-ADComputer -Filter "Name -like ''A*''"' & @CRLF & _
'$ComputersN = Get-ADComputer -Filter "Name -like ''N*''"' & @CRLF & _
'$Computers = $ComputersA + $ComputersN' & @CRLF & _
'$Jobs = @()' & @CRLF & _
'foreach ($Computer in $Computers) {' & @CRLF & _
' if ($Computer.Name -ne $null -and $Computer.Name -ne '''') {' & @CRLF & _
' $Jobs += Start-Job -ScriptBlock {' & @CRLF & _
' param($Computer)' & @CRLF & _
' if (Test-Connection -ComputerName $Computer.Name -Count 1 -Quiet) {' & @CRLF & _
' $Computer.Name' & @CRLF & _
' }' & @CRLF & _
' } -ArgumentList $Computer' & @CRLF & _
' }' & @CRLF & _
'}' & @CRLF & _
'$Results = $Jobs | ForEach-Object { $_ | Wait-Job | Receive-Job }' & @CRLF & _
'$OnlineComputers = $Results | Where-Object { $_ -ne $null }' & @CRLF & _
'if ($OnlineComputers) {' & @CRLF & _
' $OnlineComputers | ForEach-Object { Write-Output $_ }' & @CRLF & _
'} else {' & @CRLF & _
'}'
ShowDomPCs($sScript, $FileName)
; Funktion in AutoIt zum Ausführen des PowerShell-Skripts und Speichern des Ergebnisses
Func ShowDomPCs($script, $fileName)
Local $tempPsFile = $TempDir & "\tempScript.ps1"
Local $sFilePathScripts = $ScriptDir & "\" & $fileName
Local $hFile = FileOpen($tempPsFile, $FO_OVERWRITE + $FO_CREATEPATH)
If $hFile = -1 Then
ConsoleWrite("Fehler beim Erstellen der temporären PowerShell-Datei." & @CRLF)
Return
EndIf
FileWrite($hFile, $script)
FileClose($hFile)
Local $sCmd = 'powershell.exe -ExecutionPolicy Bypass -File "' & $tempPsFile & '"'
Local $iPID = Run(@ComSpec & ' /c ' & $sCmd, "", @SW_SHOW, $STDOUT_CHILD + $STDERR_CHILD)
; Warten, bis der PowerShell-Prozess beendet ist
ProcessWait($iPID)
; Überprüfen, ob die Datei erfolgreich erstellt wurde
If FileExists($sFilePathScripts) Then
ConsoleWrite("Ergebnis wurde erfolgreich in '" & $sFilePathScripts & "' gespeichert." & @CRLF)
Else
ConsoleWrite("Fehler beim Speichern des Ergebnisses." & @CRLF)
EndIf
EndFunc
Alles anzeigen
Sieht einer den Fehler? Vielen Dank noch mal
lg und schöes WE
ich hätte da einen kürzeren Ansatz.
Bezüglich mehrere Pings gleichzeitig, schau mal im Forum nach "MultiPing"
#include <Array.au3>
Local $s_PSCommand = "Get-ADComputer | Where {$_.Name -like 'W*' -Or $_.Name -like 'O*'} | Select Name"
Local $iPID = Run('Powershell.exe -Command ' & $s_PSCommand, @DesktopDir, @SW_HIDE, 6)
If ProcessWaitClose($iPID, 60) = 0 Then Exit MsgBox(0, "", "Prozess wurde nicht innerhalb von 60 Sekunden beendet.")
$aPIDOut = StringSplit(StdoutRead($iPID), @CRLF)
For $i = $aPIDOut[0] To 1 Step - 1
If $aPIDOut[$i] = "" Or StringInStr($aPIDOut[$i],"----") Or StringInStr($aPIDOut[$i], "Name ") Then _ArrayDelete($aPIDOut, $i)
Next
$aPIDOut[0] = UBound($aPIDOut) -1
;_ArrayDisplay($aPIDOut)
For $i = 1 To $aPIDOut[0]
ConsoleWrite(Ping($aPIDOut[$i],250) & @CRLF)
Next
Alles anzeigen
Ich kann im MOment die AD-Funktion nicht testen. Ist aus dem Kopf erstellt
Okay ich kann schon verstehen, dass mir hier in Puncto eingebundene Powershellscripten keiner so richtig weiterhelfen mag, ist ja schliesslich ein Autoit Forum;), Ich nehme mal an es lag an den Jobs im alten Script, was dazu führte dass die Rückmeldung nicht korrekt abgefangen wird, ich habe dieses jetzt durch folgendes ersetzt, was dazu noch wesentlich schneller ist:
Local $sScript = _
'$ComputersA = Get-ADComputer -Filter "Name -like ''A*''"' & @CRLF & _
'$ComputersN = Get-ADComputer -Filter "Name -like ''N*''"' & @CRLF & _
'$Computers = $ComputersA + $ComputersN' & @CRLF & _
'function ping2 {' & @CRLF & _
' param(' & @CRLF & _
' $Computers,' & @CRLF & _
' $TimeOut = 800 )' & @CRLF & _
' $Tasks = [System.Collections.Generic.List[Object]]::new()' & @CRLF & _
' foreach ($address in $Computers) {' & @CRLF & _
' $Tasks.Add(' & @CRLF & _
' [pscustomobject]@{' & @CRLF & _
' Target = $address.Name' & @CRLF & _
' Timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds()' & @CRLF & _
' pingTask = [System.Net.NetworkInformation.Ping]::new().SendPingAsync($address.Name, $TimeOut)} ) }' & @CRLF & _
' $Results = foreach ($Task in $Tasks) {' & @CRLF & _
' try {' & @CRLF & _
' $Task.pingTask.Wait() # Warte auf das Ende der Ping-Task' & @CRLF & _
' $Status = $Task.pingTask.Result.Status' & @CRLF & _
' $IPAddress = if ($Task.pingTask.Result.Address) { $Task.pingTask.Result.Address.IPAddressToString } else { "N/A" }' & @CRLF & _
' $Latency = $Task.pingTask.Result.RoundTripTime ; $Bytes = $Task.pingTask.Result.Buffer.Length }' & @CRLF & _
' catch {$Status = "Error" ; $IPAddress = "N/A" ; $Latency = 0 ; }' & @CRLF & _
' [pscustomobject]@{Timestamp = $Task.Timestamp; Target = $Task.Target; Status = $Status; IPAddress = $IPAddress; Latency = $Latency; Bytes = $Bytes} }' & @CRLF & _
' return $Results }' & @CRLF & _
'$PingResults = ping2 -Computers $Computers' & @CRLF & _
'$PingResults | ForEach-Object {if ($_.Status -eq "Success") {Write-Output $_.Target}}'
Alles anzeigen
Eine Frage bleibt aber noch, das script ist autark nach ca 5 Sekunden fertig, aus Autoit gestartet braucht es ca 3 - 4 mal so lange, hat einer eine Erklärung dafür? Kann man das beschleunigen?
lg und schönen Sonntag noch
wenn du alles in Powershell machen willst, warum verwendest du dann autoit?
möchte ich ja gar nicht unbeding (bin mit Sicherheit kein PD Fetischist, ja ich weiss es gibt ne udf Multiping aber das hinft mir nicht viel weiter, damit erden leider viele Rechner im unserem Netz nicht angezeigt, weil das ICMP Protokoll ausgeschaltet ist. Was ich innerhalb von Autoit bräuchte wär eine ARP Ping Unterstützung, ich weiss aber nicht ob man diese mit Autoit entsprechend nachbilden kann.
lg und schönen Tag noch