none
User Profile löschen: Get-WmiObject vs. Get-CimInstance / Arrays / Log-Files RRS feed

  • Frage

  • Hallo zusammen!

    Vorab: ich bemühe mich seit einiger Zeit mich stückweise in PowerShell einzuarbeiten, habe auch einige Bücher zum Thema ("Learn PowerShell in a Month of Luches [D. Jones, J. Hicks]", "Windows PowerShell 4.0: Das Praxisbuch [H. Schwichtenberg]", "PowerShell 5.0: Windows-Automation für Einsteiger und Profis [T. Weltner]"), komme aber leider nicht so regelmäßig und strukturiert dazu, wie man es gerne hätte...

    Vor diesem Hintergrund: please don't shoot me for obvious/stupid mistakes ():-)

    Nun habe ich aktuell eine Herausforderung, die ich gerne mit PowerShell automatisieren würde, bastel' nun schon einige Tage immer wieder daran herum, habe diverse Suchmaschinen befragt und etliche Artikel/Blogs/Forenbeiträge gelesen, komme im Moment aber nicht mehr weiter:

    Auf Win7 Clients sollen per StartUp-Skript, unter bestimmten Kriterien, ein bis mehrere lokale Benutzerprofile gelöscht werden.

    Aktuell sieht mein Skript wie folgt aus:

    $Days=30
    
    Start-Transcript -Path C:\ProfileCleanup.log -Append
    
    Write-Warning "Filtern nach User-Profilen die laenger als $Days Tage nicht genutzt wurden"
    
    Get-WmiObject -class Win32_UserProfile | Where {(!$_.special) -and ($_.localpath -ne "C:\users\administrator") -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-$Days))} | Remove-WmiObject -Verbose
    
    Stop-Transcript

    Prinzipiell funktioniert das auch einigermaßen - allerdings scheitert in einigen, nicht ganz seltenen, Fällen das Löschen des User-Ordners (C:\Users\Test), was dann im Log-file mit "RemoveWMICOMException" quittiert wird.

    Den Effekt kenne ich vom Löschen von User-Profilen via Gui ("Verzeichnis ist nicht leer").
    Manuell, per "rd /q /s c:\Users\tester" gelingt das Löschen spätestens beim zweiten Versuch.

    1.
    Die Idee wäre, mir mittels WMI Query die zu löschenden User in ein Array zu stecken, dann mit einer Schleife über selbiges zu iterieren, dabei mit Try/Catch erst die User-Verzeichnisse zu löschen und erst bei Erfolg, das User-Profil zu löschen.

    Woran ich u.A. im Moment scheitere, ist die im WmiObjekt als „LocalPath“ vorhandene Information in eine Variable zu stecken um sie z.B. an „Remove-Item –Path „Variable“ –Recurse –Force“ übergeben zu können.

    Geht das überhaupt so? Oder sollte man das besser anders aufbauen?

    2.
    Auf den Clients landen dabei Log-Files, die ich versucht habe über ein weiteres Skript einzusammeln

    $OutputFile = "C:\Test\ProfileCleanup.log"
    $ComputerListe = "C:\Test\Computerliste.txt"
    $compArray = @(Get-Content -Path $ComputerListe)
    
    for ($i=0; $i -lt $compArray.Length; $i++){
        Write-Host -ForegroundColor Cyan $compArray[$i]
        Get-Content \\ $compArray[$i] \c$\profileCleanup.log | Out-File  $OutputFile -append
        }


    Allerdings gelingt es mir leider nicht, den Client-Namen in „Get-Content –Path“ zu übergeben.

    Get-Content : Es wurde kein Positionsparameter gefunden, der das Argument "Test" akzeptiert.
    In Zeile:8 Zeichen:5
    +     Get-Content -path \\ $compArray[$i] \c$\profileCleanup.log | Out-File  $Outp ...
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (:) [Get-Content], ParameterBindingException
        + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand

    3.
    Gibt es für mein Vorhaben wesentliche Vorteile, die für „Get-CimInstance“ an Stelle von „Get-WmiObject“ sprechen würden?

    Vielen Dank im Voraus!

    Gruß TechnikSC885


    • Bearbeitet TechnikSC885 Freitag, 2. Dezember 2016 00:06 ein letzter Formatierungsversuch (inhaltlich keine Änderungen)
    Donnerstag, 1. Dezember 2016 16:31

Antworten

  • 1. Das ist leicht.

    $ProfilListe = Get-WmiObject -class Win32_UserProfile | Select-Object -ExpandProperty LocalPath

    2. Du machst Dir das Leben unnötig ein bissl schwer. Powershell kann gut mit Listen und Arrays umgehen.

    $OutputFile = "C:\Test\ProfileCleanup.log"
    $ComputerListe = Get-Content -Path "C:\Test\Computerliste.txt"
    
    Foreach($ComputerName in $ComputerListe){
        Write-Host -ForegroundColor Cyan $ComputerName
        Get-Content \\$ComputerName\c$\profileCleanup.log | Out-File  $OutputFile -append
    }
    

    3. So lange Du das Script lokal laufen lässt und Get-WMIObject den Job erledigt - Nö.  ;-)

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Bearbeitet BOfH-666 Donnerstag, 1. Dezember 2016 20:45
    • Als Antwort markiert TechnikSC885 Donnerstag, 1. Dezember 2016 23:20
    Donnerstag, 1. Dezember 2016 20:29
  • > ....aber die Referenzen aus der Registry solltest Du dennoch löschen.
     
    Das passiert automatisch, wenn Du das WMI-Objekt entfernst. Nur beim manuellen Löschen des Profilordners musst Du die Registry natürlich selber aufräumen :)
     
    Freitag, 2. Dezember 2016 09:16

Alle Antworten

  • 1. Das ist leicht.

    $ProfilListe = Get-WmiObject -class Win32_UserProfile | Select-Object -ExpandProperty LocalPath

    2. Du machst Dir das Leben unnötig ein bissl schwer. Powershell kann gut mit Listen und Arrays umgehen.

    $OutputFile = "C:\Test\ProfileCleanup.log"
    $ComputerListe = Get-Content -Path "C:\Test\Computerliste.txt"
    
    Foreach($ComputerName in $ComputerListe){
        Write-Host -ForegroundColor Cyan $ComputerName
        Get-Content \\$ComputerName\c$\profileCleanup.log | Out-File  $OutputFile -append
    }
    

    3. So lange Du das Script lokal laufen lässt und Get-WMIObject den Job erledigt - Nö.  ;-)

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Bearbeitet BOfH-666 Donnerstag, 1. Dezember 2016 20:45
    • Als Antwort markiert TechnikSC885 Donnerstag, 1. Dezember 2016 23:20
    Donnerstag, 1. Dezember 2016 20:29
  • ...oder Du nimmst einfach DelProf und löschst nicht nur die Ordner, sondern auch Referenzen in der Registry.

    EDIT: Sorry, habe die Einleitung gerade erst gelesen, dass es auch einen Lerneffekt haben sol :-)


    Evgenij Smirnov

    I work @ msg services ag, Berlin -> http://www.msg-services.de
    I blog (in German) @ http://it-pro-berlin.de
    my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
    Exchange User Group, Berlin -> http://exusg.de
    Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
    Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com


    Donnerstag, 1. Dezember 2016 20:38
  • @Olaf

    Super! Vielen Dank! :)

    Damit komme ich morgen dem gewüschten Ziel sicher um einiges näher.

    Gruß TechnikSC885

    Donnerstag, 1. Dezember 2016 23:26
  • @Evgenij

    Vielen Dank für den Hinweis. :)

    Über DelProf war ich bei meinen Recherchen auch schon gestolpert - hatte es aber, wegen dem schon erwähnten PowerShell Lerneffekt, erstmal verworfen.

    Gruß TechnikSC885

    Donnerstag, 1. Dezember 2016 23:32
  • @Evgenij

    Vielen Dank für den Hinweis. :)

    Über DelProf war ich bei meinen Recherchen auch schon gestolpert - hatte es aber, wegen dem schon erwähnten PowerShell Lerneffekt, erstmal verworfen.

    Gruß TechnikSC885


    ...aber die Referenzen aus der Registry solltest Du dennoch löschen. Erstens ist es dann sauber und zweitens ist der Lerneffekt dann noch um einiges größer ;-)

    Evgenij Smirnov

    I work @ msg services ag, Berlin -> http://www.msg-services.de
    I blog (in German) @ http://it-pro-berlin.de
    my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
    Exchange User Group, Berlin -> http://exusg.de
    Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
    Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com

    Freitag, 2. Dezember 2016 05:47
  • ...aber die Referenzen aus der Registry solltest Du dennoch löschen. Erstens ist es dann sauber und zweitens ist der Lerneffekt dann noch um einiges größer ;-)

    Evgenij Smirnov

    Danke für den Input :)

    Kommt auf die Agenda für das "Fine-Tuning" ;)
    ...zusammen mit der Optimierung der Log-Files (SID -> friendly names, Formatierung, etc.).

    Sonst noch Vorschläge/Anregungen, was in dem Kontext sinnvoller Weise mit abgedeckt werden sollte?

    Gruß TechnikSC885

    Freitag, 2. Dezember 2016 07:02
  • Sonst noch Vorschläge/Anregungen, was in dem Kontext sinnvoller Weise mit abgedeckt werden sollte?

    Gruß TechnikSC885

    Uiuiui ...  mit solchen Fragen öffnest Du die Büchse der Pandora ... wo soll man da nur anfangen?  ;-)

    Mir persönlich gefällt Dein Logging nicht so richtig. Das Transcript zu benutzen ist zwar eine sehr einfache Möglichkeit, aber auch sehr begrenzt. Ich benutze immer gern selbst erzeugte Log-Einträge. Die haben dann einen Zeitstempel und sagen aus, je nach dem, wie genau das Logging sein soll, was gerade passieren soll, was gerade passiert ist usw. usf.

    Wenn Ihr einen bestimmten Log-Viewer benutzt, z.B. CMTrace aus den SCCM-Tools, könnte man das Log auch in diesem Format schreiben.

    Dann könntest Du z.B. am Ende des Scripts, die Log-Datei auf ein Share kopieren. Dort könnte der Dateiname so angepasst werden, dass er den Ursprungscomputernamen und einen Zeitstempel enthält - das macht die Fehlersuche einfacher.

    ... und die anderen Jungs hier haben bestimmt auch noch den ein oder anderen Verbesserungsvorschlag ...


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Freitag, 2. Dezember 2016 08:44
  • > ....aber die Referenzen aus der Registry solltest Du dennoch löschen.
     
    Das passiert automatisch, wenn Du das WMI-Objekt entfernst. Nur beim manuellen Löschen des Profilordners musst Du die Registry natürlich selber aufräumen :)
     
    Freitag, 2. Dezember 2016 09:16
  • > ....aber die Referenzen aus der Registry solltest Du dennoch löschen.
     
    Das passiert automatisch, wenn Du das WMI-Objekt entfernst.

    War mir doch so, als hätte ich das im Kontext Remove-WmiObject auch irgendwo gelesen...
    ...aber die geballte Kompetenz hier hätte ich grünes Horn ohne belastbare Beweise nicht in Zweifel ziehen wollen ();-)

    Danke!

    Gruß TechnikSC885

    Freitag, 2. Dezember 2016 09:28
  • Uiuiui ...  mit solchen Fragen öffnest Du die Büchse der Pandora ... wo soll man da nur anfangen?  ;-)

    Mir persönlich gefällt Dein Logging nicht so richtig. Das Transcript zu benutzen ist zwar eine sehr einfache Möglichkeit, aber auch sehr begrenzt. Ich benutze immer gern selbst erzeugte Log-Einträge. Die haben dann einen Zeitstempel und sagen aus, je nach dem, wie genau das Logging sein soll, was gerade passieren soll, was gerade passiert ist usw. usf.

    Wenn Ihr einen bestimmten Log-Viewer benutzt, z.B. CMTrace aus den SCCM-Tools, könnte man das Log auch in diesem Format schreiben.

    Dann könntest Du z.B. am Ende des Scripts, die Log-Datei auf ein Share kopieren. Dort könnte der Dateiname so angepasst werden, dass er den Ursprungscomputernamen und einen Zeitstempel enthält - das macht die Fehlersuche einfacher.

    ... und die anderen Jungs hier haben bestimmt auch noch den ein oder anderen Verbesserungsvorschlag ...


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Danke für den Input! :)

    Hätte ich's nicht wissen wollen, hätt' ich nicht gefragt - also immer nur her damit! ;)

    Deine Hinweise zum Logging, werde ich mir auf jeden Fall genauer anschauen.
    "Transcript" waren die ersten Gehversuche - dass da noch viel Luft nach oben ist, nahm ich an ();-)

    Gruß TechnikSC885

    Freitag, 2. Dezember 2016 09:35
  • > ....aber die Referenzen aus der Registry solltest Du dennoch löschen.
     
    Das passiert automatisch, wenn Du das WMI-Objekt entfernst. Nur beim manuellen Löschen des Profilordners musst Du die Registry natürlich selber aufräumen :)
     

    Ja, so ist es vorgesehen. Ich kann mich aber an ein Projekt erinnern, wo wir danach tatsächlich aufräumen mussten, und zwar massiv. Aber die Beweise sind ja nun leider zerstört, und 2-3 Jahre her ist es auch schon, daher werden wir nie mehr erfahren, wodurch es damals zustande kam... Die Ordner waren überall weg, die Reg-Schlüssel dagegen nicht überall. Danach habe ich mir angewöhnt, das zumindest zu prüfen...

    Evgenij Smirnov

    I work @ msg services ag, Berlin -> http://www.msg-services.de
    I blog (in German) @ http://it-pro-berlin.de
    my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
    Exchange User Group, Berlin -> http://exusg.de
    Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
    Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com


    Freitag, 2. Dezember 2016 09:40
  • > ....aber die Referenzen aus der Registry solltest Du dennoch löschen.
     
    Das passiert automatisch, wenn Du das WMI-Objekt entfernst. Nur beim manuellen Löschen des Profilordners musst Du die Registry natürlich selber aufräumen :)
     

    Ja, so ist es vorgesehen. Ich kann mich aber an ein Projekt erinnern, wo wir danach tatsächlich aufräumen mussten, und zwar massiv. Aber die Beweise sind ja nun leider zerstört, und 2-3 Jahre her ist es auch schon, daher werden wir nie mehr erfahren, wodurch es damals zustande kam... Die Ordner waren überall weg, die Reg-Schlüssel dagegen nicht überall. Danach habe ich mir angewöhnt, das zumindest zu prüfen...

    Evgenij Smirnov

    ... dann nehme ich Deine Erfahrungen einfach zum Anlass, ein Reg-Cleanup als "Fingerübung" mit einzubauen... :)

    Dabei würde ich nach der entsprechenden SID suchen und betroffene Zweige entfernen?

    Gruß TechnikSC885


    Freitag, 2. Dezember 2016 10:10
  • Moin,

    die SID bekommst Du sogar als Property des WMI-Objektes geliefert. Insofern kannst Du nach dem Entfernen des Profils über WMI gleich nach dem passenden RegKey schauen.

    Aber wenn Martin sich so sicher ist, dass es 100% funktioniert, wirst Du wahrscheinlich eh nicht fündig werden...


    Evgenij Smirnov

    I work @ msg services ag, Berlin -> http://www.msg-services.de
    I blog (in German) @ http://it-pro-berlin.de
    my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
    Exchange User Group, Berlin -> http://exusg.de
    Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
    Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com

    Freitag, 2. Dezember 2016 10:16
  • Sorry - war ungenau formuliert ():-)
    "SID aus dem WMI-Objekt, dass ich löschen möchte, suche ich (nachdem ich das Userverzeichnis und das WMI-Objekt entfernt habe) in der Registry und entferne dann - falls ich fündig werde, die entsprechenden Registry-Zweige?"

    Freitag, 2. Dezember 2016 10:30
  • > "SID aus dem WMI-Objekt, dass ich löschen möchte, suche ich (nachdem ich das Userverzeichnis und das WMI-Objekt entfernt habe) in der Registry und entferne dann - falls ich fündig werde, die entsprechenden Registry-Zweige?"
     
    Das hier sind die Reg-Pfade, die ich kenne (alles unter HKLM):
     
    "Software\Microsoft\Windows\CurrentVersion\AccountPicture\Users"
    "Software\Microsoft\Windows\CurrentVersion\SystemProtectedUserData"
    "Software\Microsoft\Windows\CurrentVersion\AppReadiness"
    "Software\Microsoft\Windows\CurrentVersion\AppxAllUserStore"
    "Software\Microsoft\Windows\CurrentVersion\Group Policy\State"
    "Software\Microsoft\Windows\CurrentVersion\Group Policy"
    "Software\Microsoft\Windows\CurrentVersion\Group Policy\Status"
     
    "Software\Microsoft\Windows NT\CurrentVersion\ProfileList"
    "Software\Microsoft\Windows NT\CurrentVersion\ProfileGuid"
     
    Überall da mußt Du (ab Win 8) nach der SID suchen und sie löschen. Bei der ProfileGuid ist es schwieriger, da gibts GUID-Schlüssel, die Du aus ProfileList\<SID> ermitteln mußt.
     
    Bei Win7 haben die untersten beiden gereicht.
     
    :-)
     
    Freitag, 2. Dezember 2016 10:47
  • "Software\Microsoft\Windows NT\CurrentVersion\ProfileList"
    "Software\Microsoft\Windows NT\CurrentVersion\ProfileGuid"
     
    Überall da mußt Du (ab Win 8) nach der SID suchen und sie löschen. Bei der ProfileGuid ist es schwieriger, da gibts GUID-Schlüssel, die Du aus ProfileList\<SID> ermitteln mußt.
     
    Bei Win7 haben die untersten beiden gereicht.
     
    :-)
    Super! Vielen Dank!

    Da es im Moment nur Win7 Clients sind, kommen die beiden in die Suche - zu den übrigen merke ich mir dass es sie gibt. :)
    Freitag, 2. Dezember 2016 12:12