pixel0815
Goto Top

Per Powershell eine Verbindung zum SQL Server und AD Benutzer anlegen

Moin moin zusammen,

momentan steh ich vor folgendem Problem:

Import-Module ActiveDirectory

######## Edit Here ########

# Path to create users in
$path="OU=_Benutzer-Import,DC=xx,DC=xx"  
$user="pinneberg"  
$PWD="12345"  
$database="Pinneberg"  
$dataSource="S070"  

# Connection string to SQL Server database
#$connectionString = "Server=s070;Initial Catalog=AdventureWorks2012;Integrated Security=SSPI;"  
$connectionString = “Server=$dataSource;uid=$user; pwd=$pwd;Database=$database;Integrated Security=False;”

# Select statement to return new user accounts
# Needs to return "sAMAccountName" & "Password" columns  
# Note: Other columns names should match AD attribute name
$sql="SELECT LEFT (REPLACE(Vorname + '.' + Nachname,' ',''),20)  as sAMAccountName,  
		Vorname + '.' + Nachname + '@kit.pi' as userPrincipalName,  
		Vorname as givenName,
		Nachname as sn,
		Berufsbezeichnung as title,
		Telefon as telePhoneNumber,
		Strasse + ISNULL(CHAR(13) + CHAR(10) + Hausnummer,'') as streetAddress,  
		Stadt as l,
		Bundesland as st,
		Postleitzahl as postalCode,
		Emailadresse as mail,
		Firma as company,
		Abteilung as department,
	    Land as co,
		Webseite as wWWHomePage,
		Kennwort as Password
FROM [Pinneberg].[dbo].[vEmployee]"  

###########################

$cn = new-object system.data.sqlclient.sqlconnection
$cn.ConnectionString = $connectionString
$cn.Open()
$cmd = New-Object System.Data.SqlClient.SqlCommand
$cmd.CommandText = $sql
$cmd.connection = $cn
$dr = $cmd.ExecuteReader()

$colCount = $dr.FieldCount
$sAMAccountNameOrdinal = $dr.GetOrdinal("sAMAccountName")  
$PasswordOrdinal = $dr.GetOrdinal("Password")  

while ($dr.Read()) {
	# Get value of sAMAccountName column
	$sAMAccountName = $dr.GetValue($sAMAccountNameOrdinal)
	# Get value password column (converted to secure string for New-ADUser Cmdlet)
	$password = ConvertTo-SecureString -AsPlainText $dr.GetValue($PasswordOrdinal) -Force
		
	write-host "Creating user account..." $sAMAccountName  

	$otherAttributes = New-Object System.Collections.HashTable

	# Create a hash table of attribute names and attribute values
	# Used to populate other attributes. 
	for($i=0;$i -le $colCount-1;$i++)
	{
		$attribute = $dr.GetName($i)

		switch ($attribute)
		{
			"Password"{} 		#Ignore  
			"SAMAccountName" {} 	#Ignore  
			default{
				$otherAttributes.Add($attribute,$dr.GetValue($i))
			}
		}
	}
	# Create Active Directory User Account
	New-ADUser -sAMAccountName $sAMAccountName -Name $sAMAccountName -Path $path -otherAttributes $otherAttributes -Enable $true -AccountPassword $password 

}

$dr.Close()
$cn.Close()

Ich habe hier http://www.wisesoft.co.uk/scripts/powershell_create_ad_user_accounts_fr ... etwas gefunden was mir echt gut gefällt. Allerdings habe ich folgendes Problem

Fehler:

Ausnahme beim Aufrufen von "ExecuteReader" mit 0 Argument(en): "Die SELECT-Berechtigung wurde für das 'vEmployee'-Objekt, 'Pinneberg'-Datenbank, '
dbo'-Schema verweigert."
Bei C:\Erstelle Benutzer aus SQL Datenbank.ps1:45 Zeichen:25

back-to-top$dr = $cmd.ExecuteReader <<<< ()

+ CategoryInfo : NotSpecified: (face-smile , MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Die SQL Abfrage läuft Fehlerfrei im SQL Manager. Der Benutzer pinneberg ist ein SQL Benutzer mit eigentlich allen Rechten die man anhaken kann im SQL Manager.
Gibts da noch einen Tip?

Lieber Gruß
Heiko

Content-Key: 245483

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

Printed on: April 20, 2024 at 00:04 o'clock

Member: colinardo
colinardo Aug 04, 2014 updated at 12:04:39 (UTC)
Goto Top
Hallo Heiko,
du musst dem Benutzer auf deine Datenbank mindestens folgende Datenbankrollen freigeben: db_datareader
Die Vorgehensweise im MSSQL Management Studio:
Server > Sicherheit > Anmeldungen > Benutzer > Eigenschaften > Benutzerzuordnung: Datenbank auswählen und darunter die Datenbankrollen wählen.
mit eigentlich allen Rechten die man anhaken kann im SQL Manager.
wenn du da alles angehakt hast du hoffentlich nicht diese ausgewählt: db_denydatareader/-writer , denn diese bewirken genau das Gegenteil, nämlich die Verweigerung dieser Rechte.

Grüße Uwe
Member: pixel0815
pixel0815 Aug 04, 2014 updated at 12:57:18 (UTC)
Goto Top
Das hatte ich nicht aktiviert, habe jetzt einen anderen Benutzer genommen, nun funktioniert es fast.

Ich erhalte so eine Fehlermeldung:

Creating user account... Heiko.Test
New-ADUser : Der Typ "System.DBNull" ist ungültig.
Parametername: userPrincipalName
Bei C:\Users\heiko.wellendorf\Desktop\Erstelle Benutzer aus SQL Datenbank.ps1:77 Zeichen:12
+     New-ADUser <<<<  -sAMAccountName $sAMAccountName -Name $sAMAccountName -Path $path -otherAttributes $otherAttributes -Enable $true -AccountPa
ssword $password 
    + CategoryInfo          : InvalidArgument: (CN=Heiko.Test,O...rt,DC=kit,DC=pi:String) [New-ADUser], ArgumentException
    + FullyQualifiedErrorId : Der Typ "System.DBNull" ist ungültig.
Parametername: userPrincipalName,Microsoft.ActiveDirectory.Management.Commands.NewADUser''


Das Problem ist, dass die Daten vom SQL Server irgendwie Mist sind, ich weiß aber nicht wie ich das hinbiegen soll. Ist nicht mein Streckenpferd.
Ich glaube das Problem ist das die Felder im SQL Table zuviele Zeichen enthalten die ich aber selbst nicht setze.

Hier das Skript mit dem ich die Tabelle erstellt habe


 
USE [Pinneberg]
GO
/****** Objekt:  Table [dbo].[vEmployee]    Skriptdatum: 08/04/2014 14:28:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[vEmployee](
	[Vorname] [char](100) NOT NULL,
	[Nachname] [char](100) NOT NULL,
	[Berufsbezeichnung] [char](150) NOT NULL,
	[Telefon] [char](50) NOT NULL,
	[Strasse] [char](100) NOT NULL,
	[Hausnummer] [char](10) NOT NULL,
	[Stadt] [char](100) NOT NULL,
	[Bundesland] [char](100) NOT NULL,
	[Emailadresse] [char](100) NOT NULL,
	[Abteilung] [char](100) NOT NULL,
	[Land] [char](10) NOT NULL,
	[Webseite] [char](50) NOT NULL,
	[Postleitzahl] [char](50) NOT NULL,
	[Firma] [char](50) NOT NULL,
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF

Wenn ich dann über den SQL Manager die Daten eintippe zum t esten, dann hab ich immer ganz viele Leerschritte hinter meinem eigentlichen Text und dann kann das Skript natürlich nix damit anfangen.

Beispiel das zusammensetzen von userPrincipalName ergibt das hier mit vielen Blanks dazwischen. Wieso?

Heiko .Test @domain.loc

Edit: Ich glaub die Blanks sind das nicht. Ich hab keine Ahnung warum ein Attribut nicht im zulässigen Bereich ist face-sad
Member: colinardo
colinardo Aug 04, 2014 updated at 21:26:50 (UTC)
Goto Top
Wenn ich dann über den SQL Manager die Daten eintippe zum t esten, dann hab ich immer ganz viele Leerschritte hinter meinem eigentlichen Text und dann kann das Skript natürlich nix damit anfangen.
Logisch weil du den Datentyp [char] mit einer festen Anzahl Zeichen verwendest anstatt z.B. [nvarchar] mit einer variablen Anzahl und Unicode-Support. http://msdn.microsoft.com/de-de/library/ms186939.aspx

In Powershell müsstest du jetzt diese zusätzlichen Blanks mit Trim() vorher eliminieren. Zusätzlich solltest du Felder auf Vorhandensein überprüfen, wenn du also keinen Wert in einer Spalte stehen hast, und du das dann an New-ADUser übergibst ist die Fehlermeldung klar System.DBNull = Kein Wert in der Spalte !
Da ich hier den Inhalt deiner DB nicht sehen kann und wie Ihr die Werte in die Datenbank geschrieben habt, kann ich nur vermuten das ihr dabei einen Fehler gemacht habt vermutlich falsche Kollation(Zeichenformat) verwendet.
Nehme also zu aller erst mal das new-aduser aus dem Script heraus, und lass dir alle Spalten in der Shell ausgeben, und überprüfe sie, erst wenn hier alles korrekt ist kannst du es wieder mit new-aduser versuchen.
ich weiß aber nicht wie ich das hinbiegen soll. Ist nicht mein Streckenpferd.
dann lass diesen Part jemand anderes übernehmen.

Ich persönlich lasse mir den Inhalt einer SQL-Tabelle immer mit folgender Funktion als Datatable zurückgeben:
function Get-SQLTableContents($query,$server,$database,$username,$password){
    $conn = new-object System.Data.SqlClient.SqlConnection
    $conn.ConnectionString = “Server=$server;Database=$database;Integrated Security=False;UID=$username;PWD=$passwordtry{
            $conn.Open()
            $cmd = $conn.CreateCommand()
            $cmd.CommandText = $query
            $cmd.Connection = $conn

            $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
            $SqlAdapter.SelectCommand = $cmd
            $dt = New-Object System.Data.DataTable
            $SqlAdapter.Fill($dt) | out-null
            $conn.close()
            return $dt
        }
        catch{
            echo "Fehler: $($_.Exception.Message)"  
            $conn.close()
            return $false
        }
}

$data = Get-SQLTableContents "Select * from TestTabelle" "SERVERNAME" "DATENBANKNAME" "USERNAME" "PASSWORD"  
$data | ft -AutoSize -Wrap
Grüße Uwe