none
Ausnahme beim Aufrufen von "InvokeSet" mit 2 Argument(en RRS feed

  • Frage

  • Hallo zusammen

    Ich habe ein PS Script, das nicht macht was ich will. :-(
    Ich möchte mit dem Script bei einer Reihe von Benutzern die Terminal Server Home/Profile Einstellungen mutieren.
    Das Script sieht so aus:

    Import-Module activedirectory

    $Users = import-CSV C:\PS-Test\users.csv

    ForEach ($User in $Users){
    $Benutzer = $User.samAccountname
    $BenutzerDN = Get-ADUser -filter { cn -eq $Benutzer } -SearchBase "ou=prod,dc=domain,dc=local" | select -ExpandProperty DistinguishedName
    $Standort = "Haus1"

    $user = [ADSI] "LDAP://$BenutzerDN"
    $user.psbase.Invokeset("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
    $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
    $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
     $user.setinfo()
     }

    Im CSV habe ich drei Benutzernamen (samAccountName) zum testen eingetragen.
    Das ganze Script wird für den ersten Benutzer korrekt verarbeitet.
    Beim Durchlauf für den zweiten und dritten Benutzer wird folgende Fehlermeldung ausgegeben.
    Ich versteh aber nicht was hier falsch läuft. :-(
    Kann mir da jemand weiterhelfen?

    testuser003 (das ist der erste User. Hier funktioniert das Script noch richtig)
    testuserw709 (das ist der zweite User. Hier funktioniert das Script nicht mehr)
    Ausnahme beim Abrufen des Elements "setinfo": "Unbekannter Fehler (0x80005000)"
    Bei C:\PS-Test\TS-1User-Mutation.ps1:16 Zeichen:15
    +  $user.setinfo <<<< ()
        + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
        + FullyQualifiedErrorId : CatchFromBaseGetMember

    Ausnahme beim Aufrufen von "InvokeSet" mit 2 Argument(en):  "Unbekannter Fehler (0x80005000)"
    Bei C:\PS-Test\TS-1User-Mutation.ps1:17 Zeichen:24
    +  $user.psbase.Invokeset <<<< ("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException

    Ausnahme beim Aufrufen von "InvokeSet" mit 2 Argument(en):  "Unbekannter Fehler (0x80005000)"
    Bei C:\PS-Test\TS-1User-Mutation.ps1:18 Zeichen:24
    +  $user.psbase.invokeSet <<<< ("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException

    Ausnahme beim Aufrufen von "InvokeSet" mit 2 Argument(en):  "Unbekannter Fehler (0x80005000)"
    Bei C:\PS-Test\TS-1User-Mutation.ps1:19 Zeichen:24
    +  $user.psbase.invokeSet <<<< ("TerminalServicesHomeDrive","H:")
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException

    Ausnahme beim Abrufen des Elements "setinfo": "Unbekannter Fehler (0x80005000)"
    Bei C:\PS-Test\TS-1User-Mutation.ps1:20 Zeichen:15
    +  $user.setinfo <<<< ()
        + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
        + FullyQualifiedErrorId : CatchFromBaseGetMember


    Mittwoch, 24. Juli 2013 12:42

Antworten

  • Ich vermute mal....

    Aktive Directory hat ja die angewohnheit leere Properties nicht mit dem Objekt zurückzugeben.
    Das / Die Property(ies) beim ersten User ist/sind gefüllt und wird/werden deshalb auch mit dem Objekt ausgeliefert.
    Bei den anderen User sind diese leer, deshalb sind die Properties im Objekt garnicht vorhanden und du kannst sie auch nicht Invoken.
    Nicht vorhandene Properties verursachen meist den Fehler: "Unbekannter Fehler (0x80005000)"

    Du benutzt da verschiedenen Techniken [ADSI] und das Microsoft AD Modul. Das ist nicht nötig!
    Man sollte wenns geht, bei einer Technik bleiben! Mischbetrieb fällt durch kleine inkompatibilitäten oft auf die Nase! Oder man muss ständig konvertieren

    Mein Code benutzt nur [ADSI] und [ADSISearcher] (die Active Directory Services Klassen von .NET).

    Ich habe hier kein AD und helfe dir im Blindflug !!

    Eine der Varianten müsste es tun!

    ##################### Variante 1 ##############################
    
    
    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $user = $objSearch.FindOne()
    
        # User Properties setzen
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }
    
    ##################### Variante 2 ##############################
    
    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $SearchResult = $objSearch.FindOne()
    
        # System.DirectoryServices.SearchResult in ein System.DirectoryServices.DirectoryEntry = [ADSI] umwandeln
        $User = $SearchResult.GetDirectoryEntry()
    
        # User Properties setzen
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }
    
     ##################### Variante 3 ##############################
    
    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $SearchResult = $objSearch.FindOne()
    
        # System.DirectoryServices.SearchResult in ein System.DirectoryServices.DirectoryEntry = [ADSI] umwandeln
        $User = $SearchResult.GetDirectoryEntry()
    
        # User Properties setzen
        $user.psbase.InvokeGet("terminalservicesprofilepath")
        $user.psbase.InvokeGet("TerminalServicesHomeDirectory")
        $user.psbase.InvokeGet("TerminalServicesHomeDrive")
    
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }



     


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!



    Mittwoch, 24. Juli 2013 16:14

Alle Antworten

  • Ich vermute mal....

    Aktive Directory hat ja die angewohnheit leere Properties nicht mit dem Objekt zurückzugeben.
    Das / Die Property(ies) beim ersten User ist/sind gefüllt und wird/werden deshalb auch mit dem Objekt ausgeliefert.
    Bei den anderen User sind diese leer, deshalb sind die Properties im Objekt garnicht vorhanden und du kannst sie auch nicht Invoken.
    Nicht vorhandene Properties verursachen meist den Fehler: "Unbekannter Fehler (0x80005000)"

    Du benutzt da verschiedenen Techniken [ADSI] und das Microsoft AD Modul. Das ist nicht nötig!
    Man sollte wenns geht, bei einer Technik bleiben! Mischbetrieb fällt durch kleine inkompatibilitäten oft auf die Nase! Oder man muss ständig konvertieren

    Mein Code benutzt nur [ADSI] und [ADSISearcher] (die Active Directory Services Klassen von .NET).

    Ich habe hier kein AD und helfe dir im Blindflug !!

    Eine der Varianten müsste es tun!

    ##################### Variante 1 ##############################
    
    
    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $user = $objSearch.FindOne()
    
        # User Properties setzen
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }
    
    ##################### Variante 2 ##############################
    
    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $SearchResult = $objSearch.FindOne()
    
        # System.DirectoryServices.SearchResult in ein System.DirectoryServices.DirectoryEntry = [ADSI] umwandeln
        $User = $SearchResult.GetDirectoryEntry()
    
        # User Properties setzen
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }
    
     ##################### Variante 3 ##############################
    
    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $SearchResult = $objSearch.FindOne()
    
        # System.DirectoryServices.SearchResult in ein System.DirectoryServices.DirectoryEntry = [ADSI] umwandeln
        $User = $SearchResult.GetDirectoryEntry()
    
        # User Properties setzen
        $user.psbase.InvokeGet("terminalservicesprofilepath")
        $user.psbase.InvokeGet("TerminalServicesHomeDirectory")
        $user.psbase.InvokeGet("TerminalServicesHomeDrive")
    
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$Benutzer\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$Benutzer")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }



     


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!



    Mittwoch, 24. Juli 2013 16:14
  • Hallo Peter

    Danke viel mals für deine Antwort. Passt! :-)
    Deine Variante 2 hat mir perfekt geholfen.

    Da ich im InvokeSet noch die Variable $Benutzer verwende musste ich in deinem Script nur noch
    die Variable $Benutzer = $User.samAccountname  einbauen.
    So wird der Benutzername (samAccoutunName) aus dem CSV dann an der Stelle der Variable eingefügt.

    Danke und Gruss,
    David

    Donnerstag, 25. Juli 2013 07:38
  • Eine neue Variable ist überflüssig!
    Bei Daten die man schon in einem Objekt hat ist es unnötig diese nochmal in den Speicher zu legen!

    Nutze Daten wenns geht immer direkt! Das Spart der PowerShell meistens die Arbeit neuen Speicher zu reservieren und Variablen anzulegen.

    Die Technig die ich da benutze nennt man subexpressinon $() in der Doollar Klammer wird ein Code imn einem String mit doppelten Anführungzeichen "" ausgewertet.

    # Subexpression Demo
    "Ich bin nicht $(3*18-5) Meter gross!"

    $Standort = "Haus1"
    $Searchroot = "ou=prod,dc=domain,dc=local"
    
    $Users = import-CSV C:\PS-Test\users.csv
    
    ForEach ($User in $Users){
    
        # DirectorySearcher Objekt erstellen und mit suchkriterien füllen
        $objSearch = [ADSISearcher]"LDAP://"  # oder : New-Object System.DirectoryServices.DirectorySearcher  
        $objSearch.Filter = "(&(objectClass=user)(objectCategory=user)(sAMAccountName=$($User.samAccountname)))"
        $objSearch.SearchRoot = "LDAP://$Searchroot"
        $objSearch.PropertiesToLoad.Add("terminalservicesprofilepath") 
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDirectory")
        $objSearch.PropertiesToLoad.Add("TerminalServicesHomeDrive")
    
        # DirectorySearcher suche auslösen wir bekommen ein System.DirectoryServices.SearchResult Objekt zurück 
        $SearchResult = $objSearch.FindOne()
    
        # System.DirectoryServices.SearchResult in ein System.DirectoryServices.DirectoryEntry = [ADSI] umwandeln
        $User = $SearchResult.GetDirectoryEntry()
    
        # User Properties setzen
        $user.psbase.InvokeSet("terminalservicesprofilepath","\\domain\$Standort\Profile\$($User.samAccountname)\WinTS")
        $user.psbase.invokeSet("TerminalServicesHomeDirectory","\\domain\$Standort\Home\$($User.samAccountname)")
        $user.psbase.invokeSet("TerminalServicesHomeDrive","H:")
        $user.setinfo()
     }



    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Donnerstag, 25. Juli 2013 08:31