Question Fonction Move-HomeDir

Plus d'informations
il y a 13 ans 8 mois #8642 par EdouardG
Fonction Move-HomeDir a été créé par EdouardG
Salut à tous,
Il s'agit de mon 5ème script et est en production.
J'imagine qu'il peut sembler balourd pour les puristes mais il est efficace.

Il permet de déplacer les HomeDirectory d'utilisateurs ActiveDirectory :
- à l'unité, avec le nom d'un compte (SamAccountName)
- tous les utilisateurs d'un groupe AD
- tous les utilisateurs d'une OU
- les utilisateurs contenus dans un fichier CSV provenant d'une autre fonction (Match-HomeDir, que je posterais peut-être plus tard)

Concrètement :
- Il va créer le nouveau dossier
- Copier les données dans ce dossier
- Vérifier les données (optionnel)
- Supprimer les anciennes données si la copie est correcte (suppression optionnelle, par défaut non)
- Rendre l'utilisateur Propriétaire de ses données
- Donner le contrôle total à l'utilisateur
- Mettre à jour le profil AD de l'utilisateur en positionnant la variable HomeDir

Script très pratique pour les migrations et les réorganisations de DataCenter :)

Si vous avez des idées pour améliorer ce code, le rendre plus efficace, plus secure j'en serais très heureux :)

Ce script contient deux fonctions :
- La première qui va traiter la source et appeler la seconde avec des données \"normalisées\" pour celle-ci
- La seconde qui traitera toute l'opération de copie et de vérification.
Elles peuvent séparées ou se trouver dans le même fichier.

[code:1]
#########################################################################################
# Fonction Move-HomeDir #
###############################################################Sarou#06/01/2011#V1.1#005#

Import-Module ActiveDirectory
Function global:Move-Homedir
{
#Parametres de la commande :
param([parameter(Mandatory=$true,HelpMessage=\"Indiquez le type de source : OU, CSV, Group ou User\"«»)]$Source, [parameter(Mandatory=$true,HelpMessage=\"Indiquez le nom de la source\"«»)]$Name, [parameter(Mandatory=$true,HelpMessage=\"Indiquez un chemin de destination\"«»)]$Destination, [switch]$Remove,[switch]$Verify,[switch]$Force)
$strDomain = (Get-ADDomain)
$strDomain = $($strDomain.NetBIOSName)

if ((Test-Path $Destination) -eq $false) # Test de la présence de la destination
{
Write-Warning \"La destination : $destination n'est pas accessible\"
BREAK
}

if ($($Destination.EndsWith(\"\\"«»)) -eq $false) # Test de l'antislash à la fin du chemin
{
$Destination += \"\\"
}

Switch ($Source) # Choix de la source
{
OU
{
Write-Host \"Traitement de l'OU $Name\"
$arrUser = (Get-ADUser -Filter * -SearchBase $Name -Properties Name, DistinguishedName, HomeDirectory, SamAccountName, Description, MemberOf)
if (-not $arrUser)
{
Write-Warning \"Il n'y a pas d'utilisateur dans cette OU ou le chemin de l'OU est incorrect (attention à la casse)\"
BREAK
}
foreach ($user in $arrUser)
{
copyhdir # Execution de la fonction de copie / suppression
}
}
Group
{
Write-Host \"Traitement du groupe AD $Name\"
try
{
$strGrp = (Get-ADGroup -Identity $Name -Properties members)
}
#Récupération de l'erreur en cas de groupe inexistant :
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
Write-warning \"Le Groupe $Name n'existe pas.\"
Break
}

#Traitement des membres du groupe
Foreach ($strMember in $($strGrp.Members))
{
try
{
$User = (Get-ADUser -Filter {(DistinguishedName -eq $strMember) -and (ObjectClass -eq \"user\"«»)} -Properties Name, DistinguishedName, HomeDirectory, SamAccountName, Description, MemberOf)
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
}

copyhdir # Execution de la fonction de copie / suppression
}
}
User
{
Write-Host \"Traitement de l'utilisateur $Name\"
try
{
$User = (Get-ADUser $Name -Properties Name, DistinguishedName, HomeDirectory, SamAccountName, Description, MemberOf)
}
#Récupération de l'erreur en cas de groupe inexistant :
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
Write-warning \"L'utilisateur $Name n'existe pas.\"
Break
}
copyhdir # Execution de la fonction de copie / suppression
}
CSV
{

if ((Test-Path $Name) -eq $false) # Test de la présence du CSV
{
Write-Warning \"Le CSV : $Name n'est pas accessible ou n'existe pas\"
BREAK
}

#Import du CSV :
$arrCsv = (Import-Csv $Name -Delimiter \";\"«»)

foreach ($Line in $arrCsv)
{
$User = (Get-ADUser $($Line.LDAPLogin) -Properties HomeDirectory)
Set-Aduser -identity $User -Homedir $($Line.DossierSource)
Write-Host $($Line.DossierSource)
$User = (Get-ADUser $($Line.LDAPLogin) -Properties Name, DistinguishedName, HomeDirectory, SamAccountName, Description, MemberOf)
copyhdir # Execution de la fonction de copie / suppression
}
}
}

<#
.SYNOPSIS
Permet de déplacer de façon sécurisée et sans perte de droits les HomeDirectory des utilisateurs.

.DESCRIPTION
Move-HomeDir est une fonction qui permet de déplacer d'un espace à un autre un ou plusieurs HomeDirectory. Elle peut fonctionner explicitement pour un utilisateur, tous les membres d'un groupe Active Directory ou pour tous les utilisateurs d'une OU.
La copie est sécurisée : vérification du nombre de fichier copiés et de la taille qu'ils occupent.
Move-HomeDir créé le Home, positionne les droits Proprietaire et Contrôle total à l'utilisateur et modifie le variable HomeDirectory de l'objet utilisateur AD.

.PARAMETER Source
Parametre obligatoire. La source peut être :
- User : La fonction déplacera le Home d'un utilisateur, à préciser dans -Name
- CSV : Permet d'utiliser le fichier CSV généré par la fonction Match-HomeDir. Move-HomeDir utilise les champs FolderSource, qui contient le chemin complet du Home à migrer et LDAPLogin qui doit contenir le LDAP de l'utilisateur.
- Group : cela signifie que le script cherchera les utilisateurs dans un groupe AD à préciser dans -Name
- OU : La fonction cherchera les utilisateurs dans une Unité d'Organisation Active Directory.

.PARAMETER Name
Indiquez le nom de la source, qui peut être un utilisateur (utilisez l'identifiant SamAccountName), un groupe d'utilisateur Active Directory ou une Unité d'Organisation.
Pour cette dernière, il faut respecter scrupuleusement la casse.

.PARAMETER Destination
Indiquez le dossier racine qui contiendra les futurs HomeDirectorty.
Cela peut être un chemin local ou un chemin UNC.

.PARAMETER Remove
Valeur par défaut false, par défaut le dossier source n'est pas supprimé.
Si ce parametre est spécifié, le script supprimera les anciens Home une fois la copie et la vérification d'intégrité effectuée.

.PARAMETER Verify
Valeur par défaut false, c'est à dire que la vérification ne sera pas effectuée par défaut.
Ce paramètre va vérifier la cohèrence des fichiers copiés sur deux critères :
- Le nombre de fichier copiés doit être égal.
- La taille des fichiers doit être égal.
Même si Remove est spécifié dans la commande, si la vérification echoue le Home source n'est pas détruit par sécurité.

.PARAMETER Force
Valeur par défaut false.
Si ce parametre est spécifié et que le nouveau Home existe déjà, alors son contenu sera écrasé.
S'il n'est pas spécifié et que le nouveau Home existe déjà, alors le script s'arrête.

.INPUTS
None. You cannot pipe objects to Move-HomeDir.ps1.

.OUTPUTS
La sortie peut être redirigée.

.EXAMPLE
C:\PS> Move-HomeDir -Source User -Name edgarcia -Destination \\NAS\Home -Remove
Cette commande copiera le HomeDir de l'utilisateur edgarcia vers \\NAS\Home\edgarcia et supprimera l'ancien HomeDir.

.EXAMPLE
C:\PS> Move-HomeDir -Source Group -Name AD_Group -Destination \\NAS\Home\ -Remove -Verify
Cette commande copiera les HomeDir des utilisateurs faisant parti du groupe AD_Group vers \\NAS\Home\, supprimera les anciens HomeDir et effectuera une vérification.

.EXAMPLE
C:\PS> Move-HomeDir -Source OU -Name \"OU=Utilisateurs,DC=domain,DC=local\" -Destination \\NAS\Home\ -Force
Cette commande copiera les Homedir des utilisateurs faisant parti de l'OU Utilisateurs de domain.local, en forçant l'écrasement en cas de HomeDir déjà existantes.

.NOTES
Sarou, 06/01/2011
#>
}
Function global:copyhdir
{
if ($User.HomeDirectory) # detecte un objet user vide
{
if ((Test-Path $($User.HomeDirectory)) -eq $true) # vérifie que le HomeDirectory actuel existe
{
$strNewHome = $Destination+$($user.SamAccountName)
if (((Test-Path $strNewHome) -eq $true) -and (-not $Force))
{
Write-Warning \"Le dossier $strNewHome existe déjà, utilisez le parametre -Force pour ecraser son contenu\"
Break
}
if ($strNewHome -ne $($User.HomeDirectory)) # vérifie que la source et la destination ne sont pas identiques
{
Write-Host \"Creation du HomeDirectory $strNewHome\"
try
{
Write-Host \"Copie des données\"
Copy-Item -LiteralPath $($User.HomeDirectory) -Destination $strNewHome -Recurse:$true -Force -Confirm:$false
}
catch
{
write-warning \"Une erreur est apparue pendant la copie : $error[0]\"
}

Write-Host \"Positionnement des droits sur $strNewHome\"

$strIcaclsDomain = $strDomain + \"\\" + $($user.SamAccountName)
#positionnement des droits
& C:\Windows\system32\icacls $strNewHome /setowner <DOMAIN>\$($user.SamAccountName) /T /C | Out-Null
& C:\Windows\system32\icacls $strNewHome /grant <DOMAIN>\$($user.SamAccountName):`(OI`)`(CI`)F /T /C | Out-Null

#positionnement des variables HomeDir et HomeDrive
Set-Aduser -identity $User -Homedir $strNewHome

if ($Verify) # Routine de vérification de la taille des données copiées
{
Write-Host \"Vérification de la copie des données de $($user.samaccountname) :\"
$colItems = (Get-ChildItem $($user.HomeDirectory) -recurse -Force | Measure-Object -property length -sum -ErrorAction SilentlyContinue)
$oldSize = ($colItems.sum / 1MB«»)
$oldSize = [System.Math]::round($oldSize, 2)
$intOldCount = Get-ChildItem -path $($User.HomeDirectory) -Recurse -ErrorAction SilentlyContinue | Measure-Object -ErrorAction SilentlyContinue
$intOldCount = $($intOldCount.Count)
Write-Host \" -> Ancien dossier : $oldSize MB pour $intOldCount fichiers\"

$colItems = (Get-ChildItem $strNewHome -recurse -Force | Measure-Object -property length -sum -ErrorAction SilentlyContinue)
$newSize = ($colItems.sum / 1MB«»)
$newSize = [System.Math]::round($newSize, 2)
$intNewCount = Get-ChildItem -path $strNewHome -Recurse -ErrorAction SilentlyContinue | Measure-Object -ErrorAction SilentlyContinue
$intNewCount = $($intNewCount.Count)
Write-Host \" -> Nouveau dossier : $newSize MB pour $intNewCount fichiers\"
$strIntegrity = \"\"

if (($newSize -ne $oldSize) -or ($intOldCount -ne $intNewCount))
{
Write-Warning \"L'intégrité de la copie est douteuse : `n Ancien Home : $($user.HomeDirectory) `n Taille : $oldSize `n Nbre de fichiers : $intOldCount `n Nouveau Home : $strNewHome `n Taille : $newSize `n Nbre de fichiers : $intNewCount\"
$strIntegrity = 0
}
Else
{
Write-Host \"La copie semble ok `n\"
$strIntegrity = 1
}
}

If(($Remove) -and ($strIntegrity -eq 1)) #routine de suppression des anciens homedir
{
try
{
Write-warning \"Suppression de l'ancien homedir $($User.HomeDirectory)\"
Remove-Item -LiteralPath $($User.HomeDirectory) -recurse:$true -Force -Confirm:$false
}
catch
{
write-warning \"Une erreur est apparue pendant la suppression : $error[0]\"
}
}
Elseif ($strIntegrity -eq 0)
{
Write-Warning \"La copie des données ne semble pas parfaite, le dossier source est conservé, veuillez vérifier l'intégrité manuellement\"
}
}
Else
{
Write-Warning \"Le dossier de destination est identique au dossier source, arret du script, vérifiez votre commande\"
BREAK
}
}
Else
{
Write-Warning \"Le HomeDir source $($User.HomeDirectory)) de l'utilisateur $($User.Name) n'existe pas\"
}
}
ElseIf ($($user.Name))
{
Write-Warning \"L'utilisateur $($User.Name) n'a pas de HomeDirectory positionné dans son profil AD\"
}
}
[/code:1]<br><br>Message édité par: sarou, à: 31/01/11 16:28

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.096 secondes
Propulsé par Kunena