xpyrox
Goto Top

Remote Powershell

Guten Morgen zusammen,

ich bin grade dabei ein Script zu basteln mit dem ich an allen Rechnern in der Domain eine WMI Abfrage nach einer Webcam machen kann. Das Script soll die Rechner aus der Rechnerliste.txt einlesen und dann nach erfolgreichem auslesen eine .TXT Datei mit dem Computername lokal auf C:\Powershell\ abspeichern.

Hat jemand eine Idee wieso es nicht funktioniert?


$cred = Get-Credential -Message "Bitte geben Sie Nutzername und Passwort ein."  
$PCList = Get-Content 'C:\Powershell\Rechnerliste.txt'  

foreach ($computer in $PCList) {
    
    # Anzeige nicht erreichbarer Rechner mit Speicherung in Lokaler TXT-Datei
    if(!(Test-Connection -Cn $computer -Count 1 -quiet))  { Out-File C:\Powershell\Fehler.txt -Append -InputObject $computer -width 50 }

        # Wenn Ping Erfolgreich wird Installation und Skript ausgeführt
        if((Test-Connection -Cn $computer -Count 1 -quiet)) {

            #Dienst WinRM remote starten
            Set-Service -ComputerName $computer -Name WinRM -Status Running

            # Aufbau der Verbindung zu den Remoterechnern
            Invoke-Command -ComputerName $computer -Credential $cred {
		        
		        # Erteilung der Berechtigung auf den Remoterechnen
		        Set-ExecutionPolicy Bypass -Force


                # Script
                Get-CimInstance Win32_PnPEntity | where caption -match 'Webcam' | Out-File -FilePath C:\Powershell\$env:COMPUTERNAME.txt  
                 
            }
            
        }
    }

Content-Key: 665260

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

Ausgedruckt am: 28.03.2024 um 15:03 Uhr

Mitglied: MrCount
MrCount 30.03.2021 um 08:26:00 Uhr
Goto Top
Servus,

was kommen denn für Fehlermeldungen?
Mitglied: chkdsk
chkdsk 30.03.2021 um 08:26:43 Uhr
Goto Top
Moin,

Hat jemand eine Idee wieso es nicht funktioniert?

was bekommst du denn für eine Fehlermeldung? Wie sieht deine txt. Datei aus, die du importierst?
Mitglied: xPyrox
xPyrox 30.03.2021 aktualisiert um 08:30:22 Uhr
Goto Top
Die Fehlermeldung lautet:
Ein Teil des Pfades "C:\Powershell\Rechner1.txt" konnte nicht gefunden werden.  
    + CategoryInfo          : OpenError: (:) [Out-File], DirectoryNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
    + PSComputerName        : Rechner1

Kann es sein das er das .txt File auf dem Rechner1 ablegen will und nicht auf meinem Rechner?


in dem Textfile steht nur:
Rechner1
Rechner2
...
Mitglied: MrCount
MrCount 30.03.2021 um 08:33:57 Uhr
Goto Top
+ PSComputerName : Rechner1
sagt doch schon was aus ;)

Du machst das Out-File ja innerhalb vom Invoke-Command (Zeile 16-25)
Mitglied: MrCount
MrCount 30.03.2021 aktualisiert um 08:47:19 Uhr
Goto Top
Versuchs mal so in der Art:

...
$ScriptBlock =
{
Set-ExecutionPolicy Bypass -Force

Get-CimInstance Win32_PnPEntity | where caption -match 'Webcam'   
   
}

foreach ($computer in $PCList) {
     Invoke-Command -Computername $computer -ScriptBlock $ScriptBlock | Out-File -FilePath C:\Powershell\$computer.txt
}
...
(nicht getestet!)
Mitglied: chkdsk
chkdsk 30.03.2021 aktualisiert um 09:13:59 Uhr
Goto Top
Output ist in dem Fall direkt in der Console
$PCList = Get-Content -path 'C:\Powershell\Rechnerliste.txt'  

$ScriptBlock =
{
Set-ExecutionPolicy Bypass -Force

Get-CimInstance Win32_PnPEntity | where caption -match 'Webcam'   
try{
"{0}`t{1} Webcam vorhanden" -f (Get-Date).ToString(), $env:COMPUTERNAME  
   }
    catch {
  "{0}`t{1} Webcam nicht vorhanden" -f (Get-Date).ToString(),  $env:COMPUTERNAME  
    }
}
foreach ($computer in $PCList) {     
     Invoke-Command -Computername $computer -ScriptBlock $ScriptBlock    
}


Oder mit Output als Datei
$PCList = Get-Content -path 'C:\Powershell\Rechnerliste.txt'  

$ScriptBlock =
{
Set-ExecutionPolicy Bypass -Force
Get-CimInstance Win32_PnPEntity | where caption -match 'Webcam'   
try{
"{0}`t{1} webcam vorhanden" -f (Get-Date).ToString(), $env:COMPUTERNAME  
   }
    catch {
 "{0}`t{1} webcam nicht vorhanden" -f (Get-Date).ToString(),  $env:COMPUTERNAME  
    }
}

foreach ($computer in $PCList) {     
     $result = Invoke-Command -Computername $computer -ScriptBlock $ScriptBlock    
}
$result | Where-Object { $_ -match 'vorhanden' }           | Add-Content -Path 'C:\Powershell\vorhanden.txt' -PassThru  
$result | Where-Object { $_ -match 'nicht vorhanden' }  | Add-Content -Path 'C:\Powershell\nicht vorhanden.txt' -PassThru  
Mitglied: xPyrox
xPyrox 30.03.2021 um 10:54:28 Uhr
Goto Top
So funktioniert das ganze mehr oder weniger. Wenn keine Webcam angeschlossen ist, ist die .txt Datei natürlich leer, wenn eine Webcam angeschlosen ist steht der gewünschte Content drin. Wenn ein Rechner nicht anpingpar ist wird der Rechnername in die Datei Offline geschrieben. Soweit so gut, aber offensichtlich sind Rechner bei uns im Haus anpingbar, aber trotzdem aus sodas folgende Fehlermeldung kommt:

Set-Service : Der Dienststeuerungs-Manager auf dem Computer Rehner3 kann nicht geöffnet werden. Möglicherweise verfügen Sie nicht über die 
Berechtigung zum Ausführen dieses Vorgangs.
In Zeile:14 Zeichen:9
+         Set-Service -ComputerName $computer -Name WinRM -Status Runni ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Rechner3:String) [Set-Service], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.SetServiceCommand



#Pfad der zu importierenden Rechner
$PCList = Get-Content 'C:\Powershell\#Rechnerliste.txt'  

#Auszuführender Skriptblock
$ScriptBlock =
    {
    
    Get-CimInstance Win32_PnPEntity | where caption -match 'Webcam'   
   
    }

foreach ($computer in $PCList) {

    # Anzeige nicht erreichbarer Rechner mit Speicherung in Lokaler TXT-Datei
    if(!(Test-Connection -Cn $computer -Count 1 -quiet))  { 
        
        Out-File C:\Powershell\#Offline.txt -Append -InputObject $computer -width 50 

        }

            # Wenn Ping Erfolgreich wird Skriptblock ausgeführt
            if((Test-Connection -Cn $computer -Count 1 -quiet)) {

                Set-Service -ComputerName $computer -Name WinRM -Status Running
                Invoke-Command -Computername $computer -ScriptBlock $ScriptBlock | Out-File -FilePath C:\Powershell\$computer.txt

                }
    }
Mitglied: chkdsk
chkdsk 30.03.2021 um 13:59:39 Uhr
Goto Top
Bist du denn Admin auf der remote Kiste? Wie hast du das Skript als Admin aufgerufen? Als .ps1 abgespeichert?
Kopiere mal folgendes an den Anfang deines Skripts, somit rufst du es auch unter dem Admin Account auf.
param([switch]$Elevated)

function Test-Admin {
    $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
    $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

if ((Test-Admin) -eq $false)  {
    if ($elevated) {
        # tried to elevate, did not work, aborting
    } else {
        Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))  
    }
    exit
}

write-host "running with full privileges" -foreground "green"  

Den Service auf dem remote PC extra zu starten ist nicht nötig. mit winrm -quickconfig in deinem Invoke-command kannst du das ebenfalls erledigen, und das sogar zuverlässiger.


Hast du denn mein Skript mal durchlaufen lassen?
Mitglied: xPyrox
xPyrox 30.03.2021 um 15:17:43 Uhr
Goto Top
Bist du denn Admin auf der remote Kiste? Wie hast du das Skript als Admin aufgerufen? Als .ps1 abgespeichert?
Kopiere mal folgendes an den Anfang deines Skripts, somit rufst du es auch unter dem Admin Account auf.

Admin bin ich, habe deinen Code auch mal an den Anfang kopiert das funktioniert, danke!


Den Service auf dem remote PC extra zu starten ist nicht nötig. mit winrm -quickconfig in deinem Invoke-command kannst du das ebenfalls erledigen, und das sogar zuverlässiger.

Das hab ich jetzt nicht gecheckt wo ich winrm -quickconfig einfügen muss.

Hast du denn mein Skript mal durchlaufen lassen?

Ja, allerdings zeigt er mir nur die 'vorhandenden' an und nicht die 'nicht vorhandenen'
Mitglied: TK1987
TK1987 31.03.2021 aktualisiert um 13:33:59 Uhr
Goto Top
Moin,

Zitat von @chkdsk:
Den Service auf dem remote PC extra zu starten ist nicht nötig. mit winrm -quickconfig in deinem Invoke-command kannst du das ebenfalls erledigen, und das sogar zuverlässiger.
Wenn WinRM nicht läuft, funktioniert Invoke-Command erst gar nicht.

Den Service jedes mal zu starten ist aber dennoch überflüssig. Einmal auf den Clients auf Autostart setzen und gut ist.
Set-Service -Name WinRM -StartupType Automatic

Gruß Thomas