clschak
Goto Top

Powershell Scriptoptimierung

Hi

ich bastle gerade an einem Script um Benutzer anzulegen, die Deklaration der Variablen funktioniert an sich tadellos. Aber ich denke mal das ich hier einen riesen Umweg mache, evtl. kann mir ja mal einer auf die Sprünge helfen wie man folgendes eleganter und mit weniger Code lösen kann. (Scripten ist bei mir eher Anfängerstatus...)

Die dargestellte Funktion soll Anhand eine Auswahl zwei AD Attribute setzen (Department und Title), als erstes soll die Abteilung ausgewählt werden und dann die Funktion innerhalb der Abteilung (so wie unten dargestellt funktioniert es bereits, nur halt mit den "langen" Code)

Vielen Dank für die Denkanstöße - solche "Funktionen" sind ein paar im den gesamten Script...

Gruß
@clSchak

        write-host "[1] Vertrieb [2] Projektabwicklung [3] Einkauf [4] Produktion [5] Lager [6] Buchhaltung [7] Service"  
        $ad_abteilung = read-host "Abteilung wählen"  

        switch($ad_abteilung)
            {
                "1" {$ad_abteilung_select=1}  
                "2" {$ad_abteilung_select=2}  
                "3" {$ad_abteilung_select=3}  
                "4" {$ad_abteilung_select=4}  
                "5" {$ad_abteilung_select=5}  
                "6" {$ad_abteilung_select=6}  
                "7" {$ad_abteilung_select=7}                  
            }

            if ($ad_abteilung_select -eq 1) {
                            write-host "Gruppe: [1] Vertrieb"  
                            write-host "[1] Außendienst [2] Innendienst [3] Marketing"  
                            $ad_abteilung_select_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Vertrieb / Sales"  
                        } else {
                            if ($ad_abteilung_select -eq 2) {
                            write-host "Gruppe: [2] Projektabwicklung"  
                            write-host "[1] Projektleiter [2] BackOffice [3] Zeichner"  
                            $ad_abteilung_select_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Pojektabwicklung"  
                        } else {
                            if ($ad_abteilung_select -eq 3) {
                            write-host "Gruppe: [3] Einkauf"  
                            write-host "[1] Einkäufer [2] Reklamation"  
                            $ad_abteilung_select_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Einkauf"  
                        } else {
                            if ($ad_abteilung_select -eq 4) {
                            write-host "Gruppe: [4] Produktion"  
                            write-host "[1] Schichtleiter [2] Arbeitsvorbereitung"  
                            $ad_abteilung_select_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Produktion"  
                        } else {
                            if ($ad_abteilung_select -eq 5) {
                            write-host "Gruppe: [5] Lager"  
                            write-host "[1] Wareneingang [2] Warenausgang [3] Versand [4] Theke"  
                            $ad_abteilung_select_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Lager"  
                        } else {
                            if ($ad_abteilung_select -eq 6) {
                            write-host "Gruppe: [6] Buchhaltung"  
                            write-host "[1] Debitoren [2] Kreditoren [3] Anlagen [4] Personal [5] Mahnwesen"  
                            $ad_abteilung_select_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Buchhaltung"  
                        } else {
                            if ($ad_abteilung_select -eq 7) {
                            write-host "Gruppe: [7] Service"  
                            write-host "[1] Gebietsleiter [2] BackOffice [3] Buchhaltung [4] Außendienst [5] Lager [6] Stördienst"  
                            $ad_abteilung_final_sub = read-host "Bitte wählen:"  
                            $ad_abteilung_final = "$ad_abteilung_select.$ad_abteilung_select_sub"  
                            $ad_attibute_department = "Service"  
                        } else {
                        write-host "ERROR"  
                       }
                      }
                     }
                    }
                   }
                  }
                 }

        switch($ad_abteilung_final)
            {
                "1.1" {$ad_att_jobtitle="Vertriebs Außendienst"}  
                "1.2" {$ad_att_jobtitle="Vertriebs Innendienst"}  
                "1.3" {$ad_att_jobtitle="Marketing"}  
                "2.1" {$ad_att_jobtitle="Projektleiter"}  
                "2.2" {$ad_att_jobtitle="BackOffice"}  
                "2.3" {$ad_att_jobtitle="Technischer Zeichner"}  
                "3.1" {$ad_att_jobtitle="Einkäufer"}  
                "3.2" {$ad_att_jobtitle="Reklamationsabwicklung"}  
                "4.1" {$ad_att_jobtitle="Schichtleiter"}  
                "4.2" {$ad_att_jobtitle="Arbeitsvorbereitung"}  
                "5.1" {$ad_att_jobtitle="Wareneingang"}  
                "5.2" {$ad_att_jobtitle="Warenausgang"}  
                "5.3" {$ad_att_jobtitle="Versand"}  
                "5.4" {$ad_att_jobtitle="Theke"}  
                "6.1" {$ad_att_jobtitle="Debitormanagement"}  
                "6.2" {$ad_att_jobtitle="Kreditorenmanagement"}  
                "6.3" {$ad_att_jobtitle="Anlagenmanagement"}  
                "6.4" {$ad_att_jobtitle="Personalmanagement"}  
                "6.5" {$ad_att_jobtitle="Mahnwesen"}  
                "7.1" {$ad_att_jobtitle="Gebietsleiter"}  
                "7.2" {$ad_att_jobtitle="BackOffice"}  
                "7.3" {$ad_att_jobtitle="Buchalter"}  
                "7.4" {$ad_att_jobtitle="Service-Techniker"}  
                "7.5" {$ad_att_jobtitle="Lagerist"}  
            }

Content-ID: 274053

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

Ausgedruckt am: 23.11.2024 um 12:11 Uhr

colinardo
Lösung colinardo 09.06.2015 aktualisiert um 07:48:24 Uhr
Goto Top
Hallo clSchak,
ich würde die Daten vom Code trennen und sie dann in ein Objekt laden, so wird das ganze universeller verwendbar und übersichtlicher wenn Veränderungen oder Ergänzungen anstehen. Ich habe als Beispiel mal XML als Datenformat gewählt weil sich damit jegliche Struktur abbilden lässt, natürlich lässt sich das auch mit Arrays oder Hashtables abbilden, aber mit dem Nachteil das bei Änderungen der Abteilungen immer das Script geändert werden muss. Im Code befinden sich die XML Daten im Code, diese könnten aber Beispielsweise auch aus einer externen XML-Datei geladen werden, nur um mal die Flexibilität die du dadurch erhältst zu verdeutlichen.
Ich habe jetzt nicht alle deine Abteilungen übernommen, das hätte zu lange gedauert, aber anhand der Formatierung der XML-Daten solltest du es leicht ergänzen können.
cls
$data = @"  
<?xml version="1.0" encoding="utf-8" ?>  
<abteilungen>
	<abteilung name="Vertrieb" department="Vertrieb / Sales">  
		<unterabteilung name="Außendienst" jobtitle="Vertriebsaußendienst" />  
		<unterabteilung name="Innendienst" jobtitle="Vertriebsinnendienst" />  
		<unterabteilung name="Marketing" jobtitle="Marketing" />  
	</abteilung>
	<abteilung name="Projektabwicklung" department="Projektabwicklung">  
		<unterabteilung name="Projektleiter" jobtitle="Projektleiter" />  
		<unterabteilung name="Backoffice" jobtitle="Backoffice" />  
		<unterabteilung name="Zeichner" jobtitle="Technischer Zeichner" />  
	</abteilung>
</abteilungen>
"@  
# XML Objekt erzeugen und Daten laden
$xml = New-Object XML
$xml.LoadXML($data)

# Abteilungen auflisten
$num=0
$xml.abteilungen.abteilung.name | %{
    $num++; write-host "[$num] $_"  
}
# Abfrage Abteilung
Do{
    if ($ad_abteilung -ne $null){
        write-host "Fehlerhafte Eingabe" -ForegroundColor Yellow  
    }
    $ad_abteilung = read-host "Abteilung wählen"  
}until($ad_abteilung -ge 1 -and $ad_abteilung -le $num)

# Unterabteilung auflisten
$num=0
$xml.abteilungen.abteilung[($ad_abteilung-1)].unterabteilung.name | %{
    $num++; write-host "[$num] $_"  
}
# Unterabteilung abfragen
Do{
    if ($unter_abteilung -ne $null){
        write-host "Fehlerhafte Eingabe" -Fore Yellow  
    }
    $unter_abteilung = read-host "Unterabteilung wählen"  
}until($unter_abteilung -ge 1 -and $unter_abteilung -le $num)

# Daten aus XML Objekt ermitteln
$abteilung = $xml.abteilungen.abteilung[($ad_abteilung-1)].department
$jobtitle = $xml.abteilungen.abteilung[($ad_abteilung-1)].unterabteilung[($unter_abteilung-1)].jobtitle

# ausgewählte Daten ausgeben
write-host "Abteilungsname: $abteilung / Jobtitle: $jobtitle" -Fore Green  
Grüße Uwe
clSchak
clSchak 09.06.2015 um 07:54:02 Uhr
Goto Top
Hi

vielen Dank und ja, ich werde die Daten damit dann wohl alle in eine externe Datei auslagern, das habe ich mit den Berechtigungen auch alle gemacht, die werden dann über einer Schleife aus einer CSV importiert und lassen sich somit recht unkompliziert anpassen.

Ich habe nur ein Frage in dem Code:

$jobtitle = $xml.abteilungen.abteilung[($ad_abteilung-1)].unterabteilung[($unter_abteilung-1)].jobtitle 

-> $ad_abteilung-1

Aus welchem Grund muss man hier den Wert 1 abziehen? Fängt das auslesen der XML mit Powershell mit "0" an?
colinardo
Lösung colinardo 09.06.2015 aktualisiert um 09:15:47 Uhr
Goto Top
Aus welchem Grund muss man hier den Wert 1 abziehen? Fängt das auslesen der XML mit Powershell mit "0" an?
Arrays sind in Powershell 0-basierend genauso wie in c# deshalb musst du eins abziehen, und die einzelnen Elemente des XML-Objekts liegen halt in Arrays face-smile
Mit XML hast du aber noch ganz andere Möglichkeiten der Abfrage wo ein bestimmtes Element liegt, z.B kann man mit XPath ganz gezielt nach Elementen oder Attributen suchen.

Grüße Uwe
clSchak
clSchak 09.06.2015 um 08:25:41 Uhr
Goto Top
Danke face-smile hat mir sehr geholfen, muss jetzt nur noch hinbekommen die XML sauber einzulesen, aber das wird schon :>.
colinardo
colinardo 09.06.2015 aktualisiert um 08:46:33 Uhr
Goto Top
Danke hat mir sehr geholfen, muss jetzt nur noch hinbekommen die XML sauber einzulesen, aber das wird schon
Gerne. Das laden der XML ist ziemlich einfach, du benutzt anstatt $xml.LoadXML() die dafür vorgesehene Methode $xml.Load('c:\datei.xml')
https://msdn.microsoft.com/de-de/library/system.xml.xmldocument.load%28v ...

Viel Erfolg
Grüße Uwe
clSchak
clSchak 09.06.2015 aktualisiert um 09:12:17 Uhr
Goto Top
Das mag er so nicht:

Ausnahme beim Aufrufen von "LoadXml" mit 1 Argument(en):  "Ungültige Daten auf Stammebene. Zeile 1, Position 1."  
In C:\Users\xxxx\Desktop\script1.ps1:4 Zeichen:1
+ $xml.LoadXML('c:\script\user.xml')  
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) , MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

Edit / Add:

Gelöst ... face-smile

[xml]$xml = Get-Content user.xml
clSchak
clSchak 09.06.2015 aktualisiert um 09:15:32 Uhr
Goto Top
Die Basis sieht dann mit einem externen File wie folgt aus (vielleicht benötigt mal jemand anderes etwas ähnliches).

cls
# XML Objekt erzeugen und Daten laden
[xml]$xml = Get-Content user.xml

# Abteilungen auflisten
$num=0
$xml.abteilungen.abteilung.name | %{
    $num++; write-host "[$num] $_"  
}
# Abfrage Abteilung
Do{
    if ($ad_abteilung -ne $null){
        write-host "Fehlerhafte Eingabe" -ForegroundColor Yellow  
    }
    $ad_abteilung = read-host "Abteilung wählen"  
}until($ad_abteilung -ge 1 -and $ad_abteilung -le $num)

# Unterabteilung auflisten
$num=0
$xml.abteilungen.abteilung[($ad_abteilung-1)].unterabteilung.name | %{
    $num++; write-host "[$num] $_"  
}
# Unterabteilung abfragen
Do{
    if ($unter_abteilung -ne $null){
        write-host "Fehlerhafte Eingabe" -Fore Yellow  
    }
    $unter_abteilung = read-host "Unterabteilung wählen"  
}until($unter_abteilung -ge 1 -and $unter_abteilung -le $num)

# Daten aus XML Objekt ermitteln
$abteilung = $xml.abteilungen.abteilung[($ad_abteilung-1)].department
$jobtitle = $xml.abteilungen.abteilung[($ad_abteilung-1)].unterabteilung[($unter_abteilung-1)].jobtitle

# ausgewählte Daten ausgeben
write-host "Abteilungsname: $abteilung / Jobtitle: $jobtitle" -Fore Green  

Das entsprechende XML File:
<?xml version="1.0" encoding="utf-8" ?>  
	<abteilungen>
		<abteilung name="Vertrieb" department="Vertrieb / Sales">  
			<unterabteilung name="Außendienst" jobtitle="Vertriebsaußendienst" />  
			<unterabteilung name="Innendienst" jobtitle="Vertriebsinnendienst" />  
			<unterabteilung name="Marketing" jobtitle="Marketing" />  
		</abteilung>
		<abteilung name="Projektabwicklung" department="Projektabwicklung">  
			<unterabteilung name="Projektleiter" jobtitle="Projektleiter" />  
			<unterabteilung name="Backoffice" jobtitle="Backoffice" />  
			<unterabteilung name="Zeichner" jobtitle="Technischer Zeichner" />  
		</abteilung>
	</abteilungen>
colinardo
colinardo 09.06.2015 aktualisiert um 09:22:30 Uhr
Goto Top
Zitat von @clSchak:
Das mag er so nicht:
Kein Wunder, les meinen Post noch mal ganz genau ! Du hast anstatt wie geschrieben Load() immer noch LoadXML verwendet face-wink

Aber so kannst es natürlich auch machen, nur unter Umständen das Encoding bei Get-Content beachten.
clSchak
clSchak 09.06.2015 um 09:27:00 Uhr
Goto Top
Jap funktioniert mit beiden ",Methoden" face-smile
clSchak
clSchak 09.06.2015 um 09:45:56 Uhr
Goto Top
Dann habe ich jetzt ein Sache bzgl. XML:

$abteilung = $xml.abteilungen.abteilung[($ad_abteilung-1)].department

Wenn ich das jetzt korrekt verstehe, könnte ich in dem Bereich zwischen den beiden [ ] direkt eine Zahl eintragen und damit gezielt einen Eintrag aus der XML auswählen oder?

Im Prinzip könnte man damit auch eine "Config" erstellen und die Einstellungen dadurch gezielt abfragen oder?
colinardo
colinardo 09.06.2015 aktualisiert um 11:25:14 Uhr
Goto Top
Zitat von @clSchak:
Wenn ich das jetzt korrekt verstehe, könnte ich in dem Bereich zwischen den beiden [ ] direkt eine Zahl eintragen und damit gezielt einen Eintrag aus der XML auswählen oder?
Korrekt. Die Reihenfolge entspricht der im XML-Dokument

f75fa1eab5a6abededbc01a1ab28389f

Im Prinzip könnte man damit auch eine "Config" erstellen und die Einstellungen dadurch gezielt abfragen oder?
Wie du lustig bist.
Du hast aber wie gesagt auch die mächtigen Suchfunktionen von XPATH zur Verfügung:
Beispiel um direkt einen Node anzusprechen dessen Name-Attribut du kennst.
# Abteilung suchen
$node = $xml.SelectSingleNode('/abteilungen/abteilung[@name="Projektabwicklung"]')  
# Alle Unterabteilungen des Nodes auflisten
$node.unterabteilung
Kannst natürlich auch mehrere Nodes selektieren. Hier als Beispiel alle Unterabteilungen auflisten
# Alle UNterabteilungen auflisten
$xml.SelectNodes('//unterabteilungen')  
Mehr zu XPath kannst du hier nachlesen
Alle verfügbaren Methoden und Eigenschaften des XMLDocument-Objekts findest du hier XmlDocument-Klasse

Ach da gibt es so viele Möglichkeiten... Einfach mal die Intellisense in der ISE spielen lassen damit lernt man das ganze face-smile

Was damit noch so alles geht kannst du auch an diesem Beispiel sehen, das Einstellungen/PS-Variablen in einer XML-Datei speichert und wieder ausliest:

Grüße Uwe
clSchak
clSchak 09.06.2015 um 11:32:53 Uhr
Goto Top
Danke! face-smile das bietet einen Schwung mehr Möglichkeiten :> wie bereits oben beschrieben, bin ich in dem Bereich (noch) nicht so bewandert face-smile