giovedì 12 luglio 2007

Load all AD User in SqlServer with smo

This script loads all selected (NT user attributes) in a Sql Server Db Table for each Domain in your running forest.

To simplify script sharing I didn’t sign the script.

Script requirements:

Powersmo - Dan Sullivan

Powershell Comunity Extension 1.1.1

SqlServer whith SMO – locally installed

Script output:

Sql Server: local

Database: TempDb

Table: AdPerson (populated with all Ad User attributes)

=====================================================================================

Set-ExecutionPolicy Unrestricted

c:\temp\InitPowerSMO.ps1

$server = SMO_Server

$db = SMO_Database $server "tempdb"

# ----- Add here all AD person attribute to load in the database table ------------------------------

$variabili='Samaccountname','Mail','sn','TelephoneNumber','GivenName','ExtensionAttribute1','Mobile','proxyAddresses','distinguishedName','PhysicalDeliveryOfficeName','description','displayname','Homemdb','MSExchHomeServerName'

# ----- Generate a dynamic query to create table AdPerson ------

$query="CREATE TABLE AdPerson ("

$variabili %{ $query=$query+$($_)+' varchar(500), '}

$query=$($query+')').replace("), )","))")

# ----- drop and recreate table AdPerson -----

$DB.ExecuteNonQuery("drop table AdPerson")

$DB.ExecuteNonQuery($query)

#------ Dynamic retrieve DC name for each Ad domain ---------

$dom=Get-WmiObject Win32_NTDomain

$domall=$($dom select DomainName, DomainControllerName, DnsForestName where {$_.DomainControllerName -gt ''} %{$foresta=$_.DnsForestName; $domfo=$foresta.split('.');$domfo1=$domfo[0];$DomainName=$_.DomainName;$root=$_.DomainControllerName.replace('\\','')+'.'+$_.DnsForestName; if($DomainName -ne $domfo1.ToUpper()) {$root=$_.DomainControllerName.replace('\\','')+'.'+$DomainName+'.'+$_.DnsForestName;} $root})

#------- dynamic creation of insert-person function ------

$all='function insert-person (';

$varall=''; $variabili %{$varall=$varall+'$'+$_+','};

$all=$($all+$varall+')').replace(",)",") ");

$all=$all+"{ "" insert into AdPerson values ("

$num=0..($variabili.count-1); $num %{$all=$all+"'{"+$_+"}',"; };

$all=$($all+')').replace(",)",") ") + """ -f "+$varall.substring(0,$($varall.length-1)) + " }";

Invoke-Expression $($all)

write-host $all

# ------- generate code to insert all attributes dynamcally ----

$varall='insert-person'

$REP=@'

.REPLACE("'","''")

'@

$variabili %{ $varall=$varall+' $($_.'+$_+'.tostring())'+$REP}

# ------ for each DC - for each user -insert all selected attributes in DB table TempDb.Adperson

$domall %{$users=get-adobject -server $_ -class "User" -outvariable users -PageSize 1000; $users %{Invoke-Expression $($VARALL)} %{$DB.ExecuteNonQuery($_)} }

Scaricare tutta la foresta Ad in SqlServer? Yes.. con Powersmo e le comunity extension!


Translate in

Lo script che riporto sotto consente di creare una tabella

Con i campi specificati nella variabile $variabili.

Ho usato le Comunity extension x utilizzare la pagesize di Get-adobject in questo modo riesco ad avere performance accettabili anche con decine di migliaia di utenti.

Per l’utilizzo di questo script è necessario:

1. Installare Windows Powershell su una macchina con un’installazione di SQL server (standard o enterprise).

2. Configurare Powersmo come documentato da Dan Sullivan

3. Scaricare ed installare le Powershell Comunity Extension 1.1.1

A questo punto si è pronti a lanciare lo script ….

Lo script crea

Server: local

Database: TEMPDB

Tabella: AdPerson

e la riempie con gli attributi elencati per tutti gli utenti di tutti i domini.

Ecco lo script:

Set-ExecutionPolicy Unrestricted

c:\temp\InitPowerSMO.ps1

$server = SMO_Server

$db = SMO_Database $server "tempdb"

$variabili='Samaccountname','Mail','sn','TelephoneNumber','GivenName','ExtensionAttribute1','Mobile','proxyAddresses','distinguishedName','PhysicalDeliveryOfficeName','description','displayname','Homemdb','MSExchHomeServerName'

# ----- valorizzo la query di create table leggendo i campi sopra inseriti ------

$query="CREATE TABLE AdPerson ("

$variabili %{ $query=$query+$($_)+' varchar(500), '}

$query=$($query+')').replace("), )","))")

# ----- droppo e ricreo la tabella AdPerson -----

$DB.ExecuteNonQuery("drop table AdPerson")

$DB.ExecuteNonQuery($query)

#------ recupero dinamicamente l'elenco di 1 DC di ogni dominio ---------

$dom=Get-WmiObject Win32_NTDomain

$domall=$($dom select DomainName, DomainControllerName, DnsForestName where {$_.DomainControllerName -gt ''} %{$foresta=$_.DnsForestName; $domfo=$foresta.split('.');$domfo1=$domfo[0];$DomainName=$_.DomainName;$root=$_.DomainControllerName.replace('\\','')+'.'+$_.DnsForestName; if($DomainName -ne $domfo1.ToUpper()) {$root=$_.DomainControllerName.replace('\\','')+'.'+$DomainName+'.'+$_.DnsForestName;} $root})

$dominiAggiunti='DC1.dominio1','Dc2.Dominio2'

# ----- elenco DC domini=domini dinamici + altri domini - domini da escludere

$domall=$($domall where {$_ -ne 'DCEscluso.DominioEscluso' }) +$dominiAggiunti

#------- creo dinamicamente la funzione di insert nel DB degli utenti di AD recuperati dai DC ------

$all='function insert-person (';

$varall=''; $variabili %{$varall=$varall+'$'+$_+','};

$all=$($all+$varall+')').replace(",)",") ");

$all=$all+"{ "" insert into AdPerson values ("

$num=0..($variabili.count-1); $num %{$all=$all+"'{"+$_+"}',"; };

$all=$($all+')').replace(",)",") ") + """ -f "+$varall.substring(0,$($varall.length-1)) + " }";

Invoke-Expression $($all)

write-host $all

# ------- valorizzo in una variabile il codice x invocare la insert con l'elenco dinamico di variabili ----

$varall='insert-person'

$REP=@'

.REPLACE("'","''")

'@

$variabili %{ $varall=$varall+' $($_.'+$_+'.tostring())'+$REP}

# ------ interrogo ogni DC - X ogni utente recupero le variabili richieste e inserisco tutto nel DB

$domall %{$users=get-adobject -server $_ -class "User" -outvariable users -PageSize 1000; $users %{Invoke-Expression $($VARALL)} %{$DB.ExecuteNonQuery($_)} }