Jump to content
Bloodspiret

Powershell Scripting Import Wert aus CSV und diesen als Variable verarbeiten

Recommended Posts

Hallo Zusammen,

ich verzweifle gerade etwas.

Zur Situation:

Ich habe ein Script das unter anderem AD Gruppen anlegt, das funktioniert soweit auch alles, jetzt kam ich aber auf die Idee das anlegen der Gruppen dynamisch über eine CSV datei einzulesen.
Auch das funktioniert soweit, ich habe aber einen Wert der ein entweder als Text verarbeitet werden soll oder als Variable die ich oben im Script festgelegt habe.

Betroffener Teil im Script:

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Gruppen_ADD.csv -Delimiter ";" -encoding utf8 | Foreach{
$Name = $_.Name
$SamAccountName = $_.SamAccountName
$GroupCategory = $_.GroupCategory
$GroupScop = $_.GroupScop
$DisplayName = $_.DisplayName
$Path = $_.Pfad
If($_.Description -like "$*") {$Description = %{$_.Description}}
Else {$Description = $_.Description}
Write-Host $Description

New-ADGroup -Name $Bauvorhaben$Name -SamAccountName $Bauvorhaben$SamAccountName -GroupCategory $GroupCategory -GroupScope $GroupScop -DisplayName $Bauvorhaben$DisplayName -Path $Path -Description $Description
}

Dazugehörige csv:

Name SamAccountName GroupCategory GroupScop DisplayName Pfad Description
Security Global OU=Bauvorhaben,OU=Baulogistik,OU=Benutzergruppen,OU=Benutzerorganisation,DC=bloodspiret,DC=ddns,DC=net $Baustellenname
_Lesen _Lesen Security Global _Lesen OU=Bauvorhaben,OU=Baulogistik,OU=Benutzergruppen,OU=Benutzerorganisation,DC=bloodspiret,DC=ddns,DC=net Test
_Schreiben _Schreiben Security Global _Schreiben OU=Bauvorhaben,OU=Baulogistik,OU=Benutzergruppen,OU=Benutzerorganisation,DC=bloodspiret,DC=ddns,DC=net $Baustellenname
_Ändern _Ändern Security Global _Ändern OU=Bauvorhaben,OU=Baulogistik,OU=Benutzergruppen,OU=Benutzerorganisation,DC=bloodspiret,DC=ddns,DC=net $Baustellenname
_Zuko _Zuko Security Global _Zuko OU=Bauvorhaben,OU=Baulogistik,OU=Benutzergruppen,OU=Benutzerorganisation,DC=bloodspiret,DC=ddns,DC=net $Baustellenname


Frage:

wie verklickere ich der Powershell beim Festlegen der Variable $Description das der den Wert $Baustellenname als die oben angelegte Variable interpretieren soll und mir in der AD nicht '$Baustellenname' in die Description schreibt?

Gruß
Bloodspiret

Share this post


Link to post

Hallo und Willkommen an Board,

 

zum allgemeinen Teil:

  • Nutze bitte den Code-Tag für Code den du postest. Das erleichtert vielen das Lesen und kopieren. 

 

zum Skript:

  • In dem Skript benutzt du das Prozenz-Zeichen %, welches wiederum für ein "Foreach-Object"-Befehl steht. Das kannst du nur in einer Pipeline und nicht nach dem = nutzen. Nach dem = gibt es keine Objekte zum Verarbeiten.
  • Das $-Symbol ist ein spezielles Symbol in PS. Ersetze " durch die einfachen '. Dann möchte die Powershell nichts interpretieren.
  • Die Variable "Bauvorhaben" wurde nie definiert. Sie muss leer sein, nach deinem Code. Oder da fehlt noch was ;-) Ah! Du ließt sie als String ein. Das kann so nicht funktionieren. Da muss ein Text rein, kein angebliches Powershell-Objekt. Ich vermute, da müssen wir an dem grundliegenden Verständnis arbeiten.
  • $Name = $_.Name

    Den Teil kannst du Dir übrigens sparen, denn das kannst du unten auch einfach $_.ABC wieder angeben. Da brauchst du nicht extra noch eine neue Variable für Benutzen.

  • Es wird als CSV-Trenner ";" verwendet, was ich aber in deiner Datei nicht sehen kann.

 

Tipps:

  • In der ersten Zeile deiner CSV fehlt der Name und SamAccountName deiner Gruppe
  • Die Gruppennamen müssen eindeutig im AD sein. Das wird spätestens beim zweiten Bauvorhaben nicht mehr funktionieren
  • AD-Gruppennamen sollten selbsterklärend sein und nicht durch den Kontext der OU erklärt werden. Das erleichtert später die Administration ungemein und hilft Fehler vorzubeugen.

 

Tipps 2: Internetseiten

Edited by MurdocX
  • Like 1

Share this post


Link to post

Hallo MurdocX,

 

vielen Dank das du Dir das Thema angeschaut hast auch wenn Deine Antworten etwas an Meiner Fragestellung vorbei gehen :)

 

Ich möchte das $ Nutzen um zu identifzieren das es sich um eine im Script bereits befindliche Variable Handelt und er das importierte auch so behandelt soll. Steht das Zeichen nicht davor zu gibt er den Text direkt weiter. Das klappt auch so weit.

Bauvorhaben wurde nicht definiert: du siehst hier nur einen Teil des gesamt Scripts die Variable ist am Anfang schon definiert

Das Sparen der neuen Variablen ---> Jupp gute Idee

In der Erste Zeile fehlt der Name und SAM ---> Nein der muss leer sein, ich setze den Namen beim Anlegen aus Bauvorhaben + den Namen aus der CSV zusammen, die Erste Gruppe soll halt nur das Bauvorhaben sein ohne den in der CSV angegebenen Zusatz _ XXX. Es sind nur für einen Ordner gedachte Berechtigungsgruppen die ich später noch im ACL einfüge.

 

Ich habe meine Fragestellung nun folgendermaßen gelöst:

 

 

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Gruppen_ADD.csv -Delimiter ";" -encoding utf8 | Foreach{
$Name = $_.Name
$SamAccountName = $_.SamAccountName
$GroupCategory = $_.GroupCategory
$GroupScop = $_.GroupScop
$DisplayName = $_.DisplayName
$Path = $_.Pfad
$G_Varaible = $_.Variable.Remove(0,1)
If($_.Description -like "$*") {$Description = Get-Variable -Name $_.Description.Remove(0,1) -ValueOnly}
Else {$Description = $_.Description}
Set-Variable -Name $G_Varaible -Value $Bauvorhaben$Name

New-ADGroup -Name $Bauvorhaben$Name -SamAccountName $Bauvorhaben$SamAccountName -GroupCategory $GroupCategory -GroupScope $GroupScop -DisplayName $Bauvorhaben$DisplayName -Path $Path -Description $Description
}

 

Ich hole mir die Variable mit Get-Varibale in dem ich das erste Zeichen per remove rausnehme. Das funktioniert jetzt super. Die Frage wäre nur ob man es noch etwas besser hinbekommt.

Wenn ich zum Beispiel in der CSV 2 Variablen zusammenkette, das würde im Moment nicht funktionieren. Kann man nicht einen Befehl davor schreiben der sagt bewerte den Inhalt als Variable und nicht als Text?

Später wird das nochmal wichtig wenn ich die ACL´s setzen möchte, in einer weiteren CSV wird ein Admin diese configrieren können. HIer gibt es dann sowohl Gruppen die Dauerhaft schon in der AD sind und Gruppen die projektbezogen durch das Script angelegt werden. in der CSV wird dann zum beispiel stehen

 

 

grafik.png.e266bdc97a8918bf38e47a71991bbfcc.png

 

 

Gruß

Bloodspiret.

 

 

Hier mal das ganze Script:


#Startet das Script mit Adminrechten neu und in der Gruppe Administratoren:

If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] „Administrator“))
{   Write-Host „No Adminrights. restart as Administrator“
    $arguments = „& ‚“ + $myinvocation.mycommand.definition + „‚“
    Start-Process powershell -Verb runAs -ArgumentList $arguments
    Break
}

#Pfad auslesen

function Get-ScriptDirectory {
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}

#Abfrage der Variablen

$UStrich = "_"
$installpath = Get-ScriptDirectory
$Bauvorhaben = Read-Host 'Bauvorhaben angeben'
$Baustellenname = Read-Host 'Baustellenname angeben'
$Ordnername = "$Bauvorhaben$UStrich$Baustellenname"
$FullPath = "$installpath\$Ordnername"

#Gruppen Anlegen

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Gruppen_ADD.csv -Delimiter ";" -encoding utf8 | Foreach{
$Name = $_.Name
$SamAccountName = $_.SamAccountName
$GroupCategory = $_.GroupCategory
$GroupScop = $_.GroupScop
$DisplayName = $_.DisplayName
$Path = $_.Pfad
$G_Varaible = $_.Variable.Remove(0,1)
If($_.Description -like "$*") {$Description = Get-Variable -Name $_.Description.Remove(0,1) -ValueOnly}
Else {$Description = $_.Description}
Set-Variable -Name $G_Varaible -Value $Bauvorhaben$Name

New-ADGroup -Name $Bauvorhaben$Name -SamAccountName $Bauvorhaben$SamAccountName -GroupCategory $GroupCategory -GroupScope $GroupScop -DisplayName $Bauvorhaben$DisplayName -Path $Path -Description $Description
}

#Legt den Baustellenordner an falls nicht vorhanden

if(!(Test-Path $FullPath)) {New-Item -Path $FullPath -ItemType Directory
Write-Host -ForegroundColor Green $FullPath wurde erstellt
}
Else {Write-Host -ForegroundColor Red $FullPath ist schon vorhanden}

#Legt die Baustellenunterordner an falls nicht vorhanden

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Ordner.csv -Header "Ordner" | ForEach-Object {
$Subordner = $_.Ordner
if(!(Test-Path "$FullPath\$Subordner")) {New-Item -Path $FullPath\$Subordner -ItemType Directory
Write-Host -ForegroundColor Green $Subordner wurde erstellt
}
Else {Write-Host -ForegroundColor Red $Subordner ist schon vorhanden}
}

#Kopiert die Vorlagendateien falls nicht vorhanden

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Dateien.csv -Header "File" | ForEach-Object {
$File = $_.File
if(!(Test-Path "$FullPath\$File")) {Copy-Item -Path $installpath\Scriptdaten\Vorlagenordner\$File -Destination $FullPath\$File
Write-Host -ForegroundColor Green $File wurde kopiert
}
Else {Write-Host -ForegroundColor Red $File ist schon vorhanden}
}

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Berechtigungen_ADD.csv -Delimiter ";" | ForEach-Object {

$SubOrdnerName = $_.Ordner
If($_.Gruppe -like "$*") {$Gruppe = Get-Variable -Name $_.Gruppe.Remove(0,1) -ValueOnly}
Else{$Gruppe = $_.Gruppe}
$AccessControlType = $_.Art
$FileSystemRights = $_.Rechte
$InheritanceFlags = $_.Inheritance
$PropagationFlags = $_.Propagation
$Ordner = "$installpath\$Ordnername\$SubOrdnerName"
$GruppeID = Get-ADGroup -Identity $Gruppe
$acl = Get-Acl $Ordner
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ($GruppeID.SID, $FileSystemRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)
$acl.AddAccessRule($AccessRule)
Set-Acl -Path $Ordner -AclObject $acl -ea Stop
}

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Vererbung_DEL.csv -Delimiter ";" | ForEach-Object {
$SubOrdnerName = $_.Ordner
$Ordner = "$installpath\$Ordnername\$SubOrdnerName"
$acl = Get-Acl $Ordner
$acl.SetAccessRuleProtection($true,$true)
Set-Acl $Ordner $acl
}

Import-Csv -Path \\dc01-2019\shares\Baulogistik\Baustellen\Scriptdaten\Berechtigungen_DEL.csv -Delimiter ";" | ForEach-Object {

$SubOrdnerName = $_.Ordner
If($_.Gruppe -like "$*") {$Gruppe = Get-Variable -Name $_.Gruppe.Remove(0,1) -ValueOnly}
Else{$Gruppe = $_.Gruppe}
$AccessControlType = $_.Art
$FileSystemRights = $_.Rechte
$InheritanceFlags = $_.Inheritance
$PropagationFlags = $_.Propagation
$Ordner = "$installpath\$Ordnername\$SubOrdnerName"
$GruppeID = Get-ADGroup -Identity $Gruppe
$acl = Get-Acl $Ordner
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ($GruppeID.SID, $FileSystemRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)
$acl.RemoveAccessRule($AccessRule)
Set-Acl -Path $Ordner -AclObject $acl -ea Stop
}

 

Ich hab nun eine weitere Lösung:

 

{$Description = iex $_.Description}

Das kleine Wörtchen iex davor und es wird als Variable interpretiert statt als Text :)

Nur die Verkettung von variablen in der CSV funktioniert damit weiterhin nicht.

Edited by Bloodspiret

Share this post


Link to post
vor 5 Stunden schrieb Bloodspiret:

Wenn ich zum Beispiel in der CSV 2 Variablen zusammenkette, das würde im Moment nicht funktionieren. Kann man nicht einen Befehl davor schreiben der sagt bewerte den Inhalt als Variable und nicht als Text?

Variablen würde man z.B. so verketten:

# Erstellen des AD-Gruppennamens
$adGroupName = '{0}{1}' -f $csvItem.Bauvorhaben, $csvItem.Name

 

vor 5 Stunden schrieb Bloodspiret:

Die Frage wäre nur ob man es noch etwas besser hinbekommt.

Wenn ich das auf das Skript beziehe, dann sind quasi alle Coding-Regeln missachtet worden ;-)  Da wäre nun die Frage, ob dich das wirklich interessiert und du dort weiterkommen möchtest, oder einfach nur eine "Lösung" für dein kleines Projekt. Das eine ist weitsichtiger als das Andere. Spätestens wenn du dein eigenes Skript, oder jemand anderst dieses Debuggen muss, fängt das Grauen an :D

  • Thanks 1

Share this post


Link to post

Hallo MurdocX,

 

erneut danke für deine Antwort :)

 

Es geht mir mir hier um die Fragestellung wie kann ich in der csv datei die Variable angeben die ich im script bereits an höherer Stelle festgelgt habe.

 

Die Fragestellung ist zum teil gelöst- Nochmal zur Klarstellung:

 

Ich habe in der CSV eine Spalte namens Description, in dieser Spalte kann entweder ein manueller Wert stehen der dann so in die Description für die Gruppe angelegt wird. Es soll aber auch möglich sein sich auf eine Variable zu beziehen. In dem Fall trage ich in der CSV die Variable ein die ich im Script bereits habe.

 

Lösung 1)

in der csv steht in der Spalte Description: $Baustellenname

 

im Script steht:

If($_.Description -like "$*") {$Description = Get-Variable -Name $_.Description.Remove(0,1) -ValueOnly}

Else {$Description = $_.Description}

 

funzt ---> ist getestet

 

Lösung 2) die gefällt mir noch besser denn das ist die eigentliche Lösung die ich mir erhofft habe:

 

in der csv steht in der Spalte Description: $Baustellenname

 

im Script steht:

 

If($_.Description -like "$*") {$Description = iex $_.Description}
Else {$Description = $_.Description}

 

---> funzt ist getestet

 

Das iex oder voll ausgeschrieben Invoke-Expression sorgt dafür das er die einfachen Anführungszeichen entfernt und Powershell dies nun als Variable interpretiert als hätte ich diese direkt im Script eingetragen.

 

So mit dieser Lösung ist das eigentliche Thema geölst und ich bin fast zufrieden. Da mein Plan aber die möglichst weitgehenste Dynamisierung ist möchte ich in der csv zum Beispiel 2 bereits bestehende Variablen eintragen können, ungefair so:

 

in der csv steht in der Spalte Description: $Bauvorhaben$Baustellenname

 

im Script steht nach wie vor:

 

If($_.Description -like "$*") {$Description = iex $_.Description}
Else {$Description = $_.Description}

 

hier nimmt Powershell nun aber nur die erste Variable, die 2 wird dann nicht mehr erkannt. Würde ich hingegen die beiden Variablen in der Powershell genauso eintragen funktioniert die Verkettung.

So, und wenn diese Fragestellung gelöst ist wirds dann richtig tricky dann soll es auch möglich sein in der CSV alles in der einen Spalte, eine Verkettung aus Variablen und text einzugeben, ungefair so:

 

in der in der csv steht in der Spalte Description: $Bauvorhaben$Baustellenname_XYZ

 

 

Grundsätzlich sei gesagt, es wird da wars***einlich nie etwas anderes drinn stehen als der $Baustellenname aber ich möchte halt die dynamische möglichkeit schaffen :)

 

Gruß

Bloodspiret.

 

Share this post


Link to post

Invoke-Expression kann das lösen, hast ja selber schon gefunden. Da mußt Du halt passend mit Anführungszeichen arbeiten, dann geht das. Dazu mußt den CSV-Wert dann erst mal auf $ prüfen, wenn nein direkt verarbeiten, wenn ja mit Invoke-Expression den Variableninhalt reinschummeln. Und wenn Du in EINEM Feld gleich mehrere Variablen verwursteln willst, dann mußt Du das vorher in eine Standalone-Variable stecken und dann erst Invoke-Expression mit dieser Standalone-Variablen aufrufen. "Schön" ist aber anders. Ich kann nicht wirklich nachvollziehen, warum ein Input-Datensatz Variablen enthält, die unabhängig vom Input vorher per Skript definiert wurden...

 

 

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


Werbepartner:



×
×
  • Create New...