Migration des Profils CITRIX UPM vers FSLOGIX en « oneshot »

Petit partage de mon script powershell qui permet de migrer les profils Citrix UPM vers un conteneur FSLOGIX

Vous souhaitez migrer un « oneshot » vos profils Citrix gérés par UPM vers des profils Citrix géré par FSLOGIX ? Alors ce script est pour vous !

Le script :


#Check le repository des profils Citrix D:\Profils et pour chaque sous répertoire (exemple : D:\Profils\toto) lance la migration
Get-ChildItem -path  D:\Profils |  Where-Object { $_.PSIsContainer } |

ForEach-Object {
#A modifier en fonction des sous répertoires contenant le profil Citrix :
$path = $_.FullName + "\Win2016v6\UPM_Profile"
$sam = $_.Name
$vhdfolder = $_.FullName

#A modifier pour renommer le VHD. Je place le VHD dans le même répertoire parent du profil Utilisateur (exemple : D:\Profils\toto\Profile_toto-Citrix2016.vhdx) :
$vhd = Join-Path $vhdfolder ("Profile_"+$sam+"-Citrix2016"+".vhdx")

#Rapport en cas d'erreur
$file = "D:\Profils\1_rapport.html"

Write-host $_.Name -ForegroundColor Green
Write-Host $path -ForegroundColor Green

#Test si un VHD est déjà présent. Si non, création du VHD + montage. Si oui, montage en T: du VHD. Le check permet de faire une full en journée et le delta la nuit (plus rapide)
if (!(test-path $vhd)) {
@"
create vdisk file=$vhd maximum 8192 type=expandable

sel vdisk file $vhd

attach vdisk

create part prim

select part 1

format fs=ntfs quick

sel vdisk file=$vhd

sel part 1

assign letter=T

"@ | diskpart

Start-Sleep -s 2
#creation répertoire "Profile" dans VHD
New-Item -Path T:\Profile -ItemType directory | Out-Null
start-process icacls "T:\Profile /setowner SYSTEM"
Start-Process icacls -ArgumentList "T:\Profile /inheritance:r"
Start-Process icacls -ArgumentList "T:\Profile /grant SYSTEM`:`(OI`)`(CI`)F"
Start-Process icacls -ArgumentList "T:\Profile /grant Administrateurs`:`(OI`)`(CI`)F"
Start-Process icacls -ArgumentList "T:\Profile /grant $env:userdomain\$sam`:`(OI`)`(CI`)F"

}
else {

@"
sel vdisk file=$vhd

attach vdisk

sel part 1

assign letter=T

"@ | diskpart

}

#Migration du contenu de l'UPM vers le VHD
"Copie de $path vers T:"
$process = (Start-Process -FilePath robocopy -ArgumentList "$path T:\Profile /E /Purge /r:0" -PassThru -Wait)
Write-Output "Processus Robocopy termine avec le code suivant : "$process.ExitCode
if ($process.ExitCode -eq "1" -Or $process.ExitCode -eq "3") {
			Write-host "==Données de $sam Transférées==" -ForegroundColor Green
		}else {
			Add-Content -Path $file -Value @"
Erreur lors de la copie des données de $sam

"@
		}

#Démontage du disk vhd
@"
sel vdisk file=$vhd

detach vdisk
"@ | diskpart


Write-host "===============================" -ForegroundColor Yellow
Write-host "Fin de la création pour $sam" -ForegroundColor Yellow
Write-host "===============================" -ForegroundColor Yellow
Start-Sleep -s 3
}

Explication rapide :

Exemple avec l’utilisateur « toto » :

Le repository du profil Citrix se trouve dans : D:\Profils\toto
Dans son dossier « toto » il y a un sous dossier nommé « Win2016v6 »

Donc : D:\Profils\toto\Win2016v6 correspond à son profil Citrix géré par UPM. Son profil « WINDOWS » est présent à l’intérieur, dans le dossier « UPM_Profile ». Donc le chemin complet de son profil windows est : D:\Profils\toto\Win2016v6\UPM_Profile
Le but étant de copier le contenu du « UPM_Profile » et de le coller dans un conteneur FSLOGIX, le vhdx.
Le conteneur FSLOGIX, via le script, sera créé dans le répertoire : D:\Profils\toto

Quelques points rapides :

  • La migration ne supprime rien du profil UPM (simple copie) donc un retour en arrière est possible.
  • Pensez à modifier les variables : $path $vhdfolder et $vhd si vous souhaitez déplacer le vhd autre part que dans le répertoire parent de l’utilisateur.
  • Laissez bien les « sleep » ainsi que les espaces dans le block script de diskpart.
  • Un fichier de log (basic) est créé et alimenté à chaque fois que robocopy renvoi un code « exit » différent de 1 ou 3. A perfectionner.

Lister et Désactiver les Comptes Citrix Gateway (NetScaler Unified Gateway)

Hey ! Ça fait longtemps que j’avais pas publié un article sur mon site !
Changement de vie personnelle fut radi ….. « On s’en fout !!! On veut ton script !!!!! »

Aujourd’hui je vous propose un script permettant de lister les Utilisateurs AD ayant un accès NetScaler Unified Gateway et de les désactiver en un clic !

Cas pratique :
Un utilisateur ne doit plus faire de « télé travail » (pour X raisons) et dispose d’un téléphone personnel sur lequel il avait un accès distant à Citrix (Via authentification à double facteur ‘Google Authenticator’).
Vous ne pouvez pas désactiver le compte AD car cela signifie qu’une fois au bureau il ne pourra plus se connecter. Vous devez donc lui supprimer l’ « Enrollement » de son téléphone.

L’enrollement du téléphone se situe dans un attribue AD : « UserPreference » et est délimiter par un @# au début et une « , » à la fin :

ATTENTION : Cet attribut ne contient pas que cela. Il peut arriver qu’il y ait d’autres paramètres de renseignés.

La requête Powershell :

Get-ADUser -LDAPFilter "(userParameters=*#@*,*)" | Select Name,SamAccountNam

« Oui mais Xavier, tu avais parler de lister et désactiver en un clic !!!! »

Effectivement, j’ai créé une application pour que nos personnes de l’exploitation/support puissent désactiver les accès Unified Gateway sans à avoir à modifier les attributs directement dans l’AD.
Ce que je vous propose c’est ceci :

Pour le moment :
– Un Bouton pour désactiver + confirmation avant désactivation
– Un Bouton pour Quitter

Attention, vous ne pouvez sélectionner qu’un User à la fois

Le code de l’application :

#Modules
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
ipmo activedirectory
$image = [system.drawing.image]::FromFile("D:\script\citrix_netscaler.jpg")

function liste {
#Paramètre de la fenêtre
$Form = New-Object System.Windows.Forms.Form
$Form.AutoSize = $True
$Form.text = "Selection de l'accès distant à désactiver"
$Form.MaximizeBox = $false

#Header avec Image (pour faire genre c'est beau)
$Header = new-object Windows.Forms.PictureBox
$Header.width=200
$Header.height=80
$Header.top=10
$Header.left=10
$Header.Image=$image
$header.SizeMode = 'StretchImage'
$form.Controls.Add($Header)

#Creation de la liste à cocher
$ListeCTX=New-Object System.Windows.Forms.CheckedListBox
$ListeCTX.Location = '10,100'
$ListeCTX.Size = '250,300'
$form.Controls.Add($ListeCTX)
$ctx = Get-ADUser -LDAPFilter "(userParameters=*#@*,*)" | Select Name,SamAccountName
$ListeCTX.DataSource = [collections.arraylist]$ctx
$ListeCTX.DisplayMember = 'SamAccountName'
$ListeCTX.CheckOnClick = $true

# Bouton désactiver l'accès distant
$BoutonDisable= new-object System.Windows.Forms.Button
$BoutonDisable.Location = '280, 100'
$BoutonDisable.Size = '150,50'
$BoutonDisable.Text = 'Désactiver'
$BoutonDisable.add_click({
$ListeCTX.CheckedItems | select SamAccountName
$Users =[array]$($ListeCTX.CheckedItems).SamAccountName
$reponse = confirmation "Voulez vous vraiment désactiver l'accès distant de $Users ?" "Confirmer"
if ($Reponse -eq [System.Windows.Forms.DialogResult]::Yes)
{
Write-Host "désactivation de l'accès distant de $Users"
$User = $Users
Write-Host $User -ForegroundColor Red
$KeyNOW = Get-ADUser -Filter "sAMAccountName -eq '$User'" -Properties * | Select-Object -ExpandProperty userParameters
$KeyNEW = $KeyNOW -replace '(?<=#@)(.*)(,)'
Write-Host $KeyNOW -ForegroundColor Yellow
Write-Host $KeyNEW -ForegroundColor Green
Set-ADUser -Identity "$User" –replace @{userParameters=$KeyNEW} -Verbose | OK "L'utilisateur $User n'a plus d'accès à distance" "Opération réussie"
}
else
{
Write-Host "annulation"
}
})
$form.Controls.Add($BoutonDisable)

#CopyRight
$CopyRight = New-Object Windows.Forms.Label
$CopyRight.Location = New-Object Drawing.Point 370,410
$CopyRight.Size = New-Object Drawing.Point 110,15
$CopyRight.text = "Copyright XBI. Version 2"
$CopyRight.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 7)
$form.Controls.Add($CopyRight)

#Bouton Quitter
$BoutonQuitter= new-object System.Windows.Forms.Button
$BoutonQuitter.Location = '50, 410'
$BoutonQuitter.AutoSize = $True
$BoutonQuitter.Text = 'Quitter'
$BoutonQuitter.add_click({
$form.Close()
})
$form.Controls.Add($BoutonQuitter)

[void]$Form.ShowDialog()
}

function confirmation { 
$message_Out = $args[0]
$titre= $args[1]
$Btn = 4  
$Icon = 48
Return [System.Windows.Forms.MessageBox]::Show($Message_Out, $Titre , $Btn, $Icon)
} #Generation fenetre de confirmation

function OK { 
$message_Out = $args[0]
$titre= $args[1]
$Btn = 0  
$Icon = 48
[System.Windows.Forms.MessageBox]::Show($Message_Out, $Titre , $Btn, $Icon)
} #Generation fenetre OK

liste

A modifier :
- La variable $image (afin d'avoir une jolie image en haut à gauche) Peu importe la taille de l'image : $header.sizemode est là pour "fit" l'image dans le "header".

La partie la plus intéressante du script est celle ci :

$KeyNOW = Get-ADUser -Filter "sAMAccountName -eq '$User'" -Properties * | Select-Object -ExpandProperty userParameters 
$KeyNEW = $KeyNOW -replace '(?<=#@)(.*)(,)'
Write-Host $KeyNOW -ForegroundColor Yellow
Write-Host $KeyNEW -ForegroundColor Green

La variable $keyNOW correspond à la chaîne de caractère située dans l’attribut "userParameters"
Cette valeur est ensuite éditée via un RegHEx (merci au site :
https://regexr.com/ ) pour y extraire la valeur située entre le #@ et la virgule (donc le paramétrage de l'accès distant). La valeur devient donc $KeyNEW

Le write-host est uniquement là pour le debug (vous pouvez tester cette partie du script sans aucune crainte car il n'y a aucune modification de faite sur le User.

Avant désactivation de mon accès :

Après désactivation de mon accès :

Créer des VM en MASSE via script !!

Avant propos :

Ce script est « fait maison » et avec le cœur. Oui, il n’est pas parfait et oui, il y a surement des optimisations à faire, mais il fonctionne et surtout j’y ai passé du temps dessus…
Je suis ouvert à toute proposition d’amélioration, dans le respect bien-sur ! sinon allez vous faire … 🙂

Version :
V1 – Diffusion 10/04/2019

Prérequis :

  • PowerCLI sur le serveur ou PC allant lancer le script
  • Un compte ayant les droits de création de machine virtuelle
  • Un profil de machine virtuelle (vous savez, le « truc » que personne n’utilise dans le vCenter nommé « Gestionnaire de spécification de personnalisation » )
  • Un Template parfait (voir mon autre article « Comment créer une machine virtuelle)

Que va faire le script ?

  1. Se connecter au vCenter
  2. Chercher si les machines virtuelles existent déjà
  3. Créer X machines virtuelles via un template et un profil de VM sur un host aléatoire en fonction du nombre de Host disponible (mention spéciale aux personnes n’ayant pas le DRS de configuré :p )
  4. Vous informer de l’avancement des tâches de création
  5. Les démarrer après création afin que le profil de VM s’applique.

J’insiste sur le fait que le Profil de VM doit être créé et configuré. C’est simple à faire depuis le vCenter, et c’est un gain de temps considérable pour la configuration des machines virtuelles après création.

Pour rappel : le Profil de VM permet de configurer la machine virtuelle dès le premier démarrage de celle-ci. On peut configurer le hostname, la licence, la configuration réseau, joindre la VM au domaine etc ….. !

Le Script :

j’ai commenté suffisamment le script pour qu’il soit facile à lire et modifier. Dans cette exemple ci dessous, je l’applique à un environnement VDI (ce qui explique le nom des VM) mais cela fonctionne aussi dans un environnement standard…)

Les variables :

Les variables à modifier OBLIGATOIREMENT sont :


$vcenterXBI ##le nom d'hôte ou IP du VCENTER
$datastoreXBI ##Variable pour le Datastore de destination de l'ensemble des futurs VMs
$nbreHoteXBI ##Nombre d'hote ESX dans le cluster
$modeleXBI ##Le modèle de base (template obligatoire)
$poolVMXBI ##Nom du pool de ressource, pas obligatoire, vous pouvez supprimer si jamais
$personnalisationXBI ##Fichier de personnalisation créé depuis le vcenter (vous savez le fameux "Gestionnaire de spécification de personnalisation"
$nomVMXBI ##Nom des futurs VM, le {0} corresponds au numéro, exemple "maison{0}" va créer maison1, maison2 etc...

Le script complet :


Clear
Add-PSSnapIn VMware.VimAutomation.Core  #powercli
####### VARIABLES #######
$vcenterXBI = "nom du vcenter"                               ##le nom d'hôte ou IP du VCENTER
$userXBI = Read-Host -Prompt "Nom d'utilisateur"             ##Prompt pour l'utilisateur
$passwordXBI = Read-Host -Prompt "mot de passe"              ##Prompt pour le mot de passe
$datastoreXBI = "vsanDatastore"                              ##Variable pour le Datastore de destination de l'ensemble des futurs VMs
$nbreHoteXBI = "4"                                           ##Nombre d'hote ESX dans le cluster
$modeleXBI = "VDI-2k12-GOLD"                                  ##Le modèle de base (template)
$nombreVMXBI = Read-Host -Prompt "Nombre de VM à cloner ?"   ##Prompt pour le nombre de VM à créer
$poolVMXBI = "VDI-2K12"                                        ##Nom du pool de ressource, pas obligatoire, vous pouvez supprimer si jamais
$personnalisationXBI = 'Windows2k8-VDI'                      ##Fichier de personnalisation créé depuis le vcenter
$nomVMXBI = "VDI-TEST-{0}"                                   ##Nom des futurs VM, le {0} corresponds au numéro, exemple "maison{0}" va créer maison1, maison2 etc...  
###### FIN DES VARIABLES #######

Connect-VIServer -Server $vcenterXBI -User $userXBI -Password $passwordXBI
$spec = Get-OSCustomizationSpec -Name $personnalisationXBI

function creation {
    1..$nombreVMXBI | foreach{
        $vmNom = $nomVMXBI -f $_
        $vm = Get-VM -Name $vmNom
            if ($vm) {
                "{0} exists" -f $vmNom
                Write-Host "Machines existent déjà" -ForegroundColor Red
                exit
                Disconnect-VIServer -Confirm:$false
                     }
            else {
                $numHost = get-random -Maximum $nbreHoteXBI         ##genere un nombre         
                $esx = (Get-VMHost)[$numHost]                    ##selectionnne un hote en fonction du nombre au dessus
                $esx | New-VM -Name $vmNom -Template $modeleXBI -Datastore $datastoreXBI -OSCustomizationSpec $spec -ResourcePool $poolVMXBI -RunASync
                 }
}
}
Clear
function log {
              Do {
              Clear
              Get-Task | Where-Object { $_.name -eq "CloneVM_Task" -and $_.State -eq "Running"} | Format-Table
              sleep 10
              Clear
}
              until ((Get-Task | Where-Object { $_.name -eq "CloneVM_Task" -and $_.State -eq "Running"}) -eq $Null)}

function StartdesVM {
    1..$nombreVMXBI | foreach{
                          $vmNom = $nomVMXBI -f $_ 
                          Start-VM -VM $vmNom
                          sleep 3
                          }
}

creation #fonction de creation des VM
log #fonction de log interractif
StartdesVM #demarrage des VM

Write-Host "Machines virtuelles crées et démarrées, merci de patienter le temps que le profil de VM s'applique !" -ForegroundColor Yellow
Disconnect-VIServer -Confirm:$false

Résultat :

J’ai lancé la création de trois machines virtuelles :

Pendant la création des VM :

A la fin de l’exécution du script :

Sur mon pool de ressource dans le vCenter :


Télécharger des fichiers à l’aide de BITS (Windows 7 et Windows 10)

Intérêt ?

Vous souhaitez télécharger un gros fichier (plusieurs GB) mais sans surcharger le lien ? Le transfert BITS est fait pour vous (et ce script aussi).

Avantage :

  • Gestion par queue
  • Taux de transfert modifiable
  • Soumis à la QOS
  • Capacité de reprise (si le serveur en face l’accepte)
  • Téléchargement de fichiers / dossiers sous dossier etc
  • Possible téléchargement multiple.

Inconvénient :

  • Pas « user-friendly »

Téléchargement standard :

saturation de la bande passante

Téléchargement BITS :

téléchargement par « pic », ne saturant plus le lien.

Le script :

Dans cette exemple, nous allons télécharger une ISO Ubuntu de quelques giga (voir la variable $source)
Une fois le téléchargement complété, cette ISO sera ensuite stockée dans un répertoire (voir la variable $destination)

Concernant la source, elle peut être :
– Un fichier (dans un répertoire réseau ou sur internet)
– Un répertoire avec des fichiers (dans un répertoire réseau)

Concernant la destination, elle DOIT être :
– Si on récupère un fichier, la destination DOIT être un fichier. Par exemple, si on télécharge un ISO, la destination doit être C:\XXX\XXX\monfichier.iso
– Si on récupère un répertoire/sous répertoire, la destination DOIT être un répertoire.


Les clefs de registre du début sont là pour configurer BITS (débits et mode) Pour le moment, je n’ai pas trouvé d’autres moyens (si quelqu’un à une idée… :p )

Version avec Proxy :

#Configuration de BITS.
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v EnableBITSMaxBandwidth /t REG_DWORD /d 1 /f
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxBandwidthValidFrom /t REG_DWORD /d 8 /f
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxBandwidthValidTo /t REG_DWORD /d 17 /f
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxTransferRateOffSchedule /t REG_DWORD /d 90000 /f #valeur à modifier pour brider (en Kbit/s)
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxTransferRateOnSchedule /t REG_DWORD /d 90000 /f #valeur à modifier pour brider (en Kbit/s)
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v UseSystemMaximum /t REG_DWORD /d 0 /f

#Authentification Proxy
$ProxyCred = Get-Credential -Message "Proxy Auth"
$source = "http://mirrors.phx.ms/ubuntu-cd/18.04.2/ubuntu-18.04.2-desktop-amd64.iso" #exemple : "T:\XXXXX\XXXXX\macon.doc" ou "T:\XXXXX\XXXXX\*.*" pour copier l'ensemble des répertoires/fichiers
$destination = "C:\Tempo\ubuntu.iso" #exemple : "C:\temp\" ou "C:\temp\macon.doc"

Start-BitsTransfer -Source $source -Destination $destination -Priority low -ProxyUsage SystemDefault -ProxyAuthentication basic -ProxyCredential $ProxyCred -TransferType Download

Version sans proxy :

#Configuration de BITS.
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v EnableBITSMaxBandwidth /t REG_DWORD /d 1 /f
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxBandwidthValidFrom /t REG_DWORD /d 8 /f
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxBandwidthValidTo /t REG_DWORD /d 17 /f
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxTransferRateOffSchedule /t REG_DWORD /d 90000 /f #valeur à modifier pour brider (en Kbit/s)
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v MaxTransferRateOnSchedule /t REG_DWORD /d 90000 /f #valeur à modifier pour brider (en Kbit/s)
REG add "HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS" /v UseSystemMaximum /t REG_DWORD /d 0 /f

$source = "http://mirrors.phx.ms/ubuntu-cd/18.04.2/ubuntu-18.04.2-desktop-amd64.iso" #exemple : "T:\XXXXX\XXXXX\macon.doc" ou "T:\XXXXX\XXXXX\*.*" pour copier l'ensemble des répertoires/fichiers
$destination = "C:\Tempo\ubuntu.iso" #exemple : "C:\temp\" ou "C:\temp\macon.doc"

Start-BitsTransfer -Source $source -Destination $destination -Priority low -TransferType Download

Lancement du script :

Vous devez être administrateur du PC pour pouvoir lancer le script.
Pensez aussi à faire un :

Set-ExecutionPolicy Unrestricted

… pour autoriser l’exécution des scripts.

Lors que vous lancerez le script, le téléchargement se lancera automatiquement, une « barre » de progression s’affichera aussi :

Activer Windows 10 lors d’un déploiement MDT à travers un Proxy.

Principe / cas pratique :

Vous souhaitez activer Windows 10 lors d’un déploiement MDT mais vous êtes derrière un proxy et le compte Local du PC utilisé pendant le déploiement n’a pas accès à internet. Que faire ?

Mettre un script lors du déploiement pour simuler une connexion au proxy via un compte de service qui a accès à internet.

Lets Go :

Afin de faire les choses proprement et ne pas mettre de mot de passe en claire dans le script, nous allons générer une clef contenant le mot de passe du compte. Vous allez donc avoir besoin de ceci en premier :

$masecurestring = ConvertTo-SecureString -AsPlainText 'MOT DE PASSE DU COMPTE QUI DEVRA SE CONNECTER AU PROXY' -force
$maclef = $masecurestring | ConvertFrom-SecureString
$CheminRepertoireClef = "chemin daccess pour stocker la clef"
out-file -filepath "$CheminRepertoireClef\MaClef.txt" -InputObject $maclef 
#Ecriture du résultat dans le fichier MaClef.txt

! Pensez à supprimer le mot de passe rentré dans le script une fois le fichier généré !

Une fois le fichier généré, stockez le quelque part en attendant la suite.

Le script d’activation :

Le script va faire appel au .NET suivant :
System.Net.WebProxy, System.Net.WebClient, System.Net.NetworkCredential permettant la communication vers internet via un proxy + authentification.
Il y a aussi une requête WMI pour trouver la clef d’activation Windows 10 lié au matériel et l’installer.

Il faut changer les variables suivantes pour que cela « match » avec votre environnement :

$Username= "Nom d'utilisateur, exemple : CORPO\utilisateur ou utilisateur etc.."
$MaClef= "chemin vers le fichier"
$WebProxy= New-Object System.Net.WebProxy("IP:PORT DU PROXY",$true)

Le script entier :


$Username= "Nom d'utilisateur, exemple : CORPO\utilisateur ou utilisateur etc.."
$MaClef= "chemin vers le fichier"
$Password= Get-Content $MaClef | ConvertTo-SecureString
$WebProxy= New-Object System.Net.WebProxy("IP:PORT DU PROXY",$true)
$url="http://google.fr"

#Configuration proxy
Write-Host "Configuration du Proxy pour l'activation Windows"
$WebClient = New-Object System.Net.WebClient
$WebClient.Proxy=$WebProxy
$WebClient.Proxy.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)

#Init dun telechargement pour confirmer lauth proxy
$WebClient.DownloadData($url)

#Interrogation pour recup la clef et l'installer
Write-Host "Get de la Clef Windows depuis le bios"
$keyrecup = powershell "(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey"
$computer = gc env:computername
$service = get-wmiObject -query "select * from SoftwareLicensingService" -computername $computer
$service.InstallProductKey($keyrecup)
$service.RefreshLicenseStatus()

#activation de windows
Write-Host "Activation de Windows, veuillez patienter"
#Creation dun job pour lactivation
Start-Job -ScriptBlock {start-process cmd.exe -ArgumentList "/C slmgr.vbs /ato"}

Je pense que le script est suffisamment commenté pour que vous puissiez comprendre ce qu’il fait. Je vous conseille de le tester avant de le mettre en production sur le MDT. Les erreurs sont assez explicites :

Ici , c’est un problème avec le mot de passe ou le compte utilisé pour s’authentifier sur le proxy.

Créer une tâche sur le MDT :

  1. Copier le script Powershell et le fichier MaClef.txt dans le répertoire de votre DeploiementShare. Dans mon cas, le répertoire se trouve içi :
     » C:\MDT\Scripts « 
  2. Modifier le script afin d’avoir cette variable là (pour faire simple , on signale au script que la clef se trouve dans le même répertoire) :
$MaClef= "C:\MDT\Scripts\MaClef.txt"
devient :
$MaClef= ".\MaClef.txt"

3. Éditez votre « Task Sequence » préféré :

4. Allez dans le deuxième onglet puis dans la catégorie « State Restore »

5. Cliquez sur « Add » puis « General » et enfin « Run Command Line »

Et non pas « Run PowerShell Script »

6. Éditez votre nouvelle tâche « Command Line » comme ci dessous :

La « Command Line » si vous souhaitez faire un « copier coller » :

Powershell.exe -ExecutionPolicy ByPass -File "%SCRIPTROOT%\MDT_activation_windows.ps1"

7. Dans les « Options » de la tâche, vous pouvez cocher « Continue on Error » pour éviter que le script ne fasse stopper votre déploiement. Vous pourrez toujours lancer le script à la main à la fin du déploiement.

Sonde Centreon : Check si une IP est en cours d’utilisation et l’afficher dans la supervision

Principe / cas pratique :

Lorsqu’un intervenant/prestataire vient chez nous (mon client) faire une maintenance/intervention, il peut arriver qu’on lui fournisse une IP pré définie « bypassant » le proxy/firewall. Il est important de savoir quant elle est utilisée. Il faut donc la superviser.
Grosso Modo, c’est un check_ping avec un code de retour inversé en fonction du résultat.

Si l’IP est en cours d’utilisation, alors la sonde est « Critical » et remonte dans la supervision. Si ce n’est pas le cas, la sonde est « OK »

NB: Il existe surement une autre solution mais, pourquoi faire simple quand on peut faire compliqué ? non ?

Lets Go :

Connectez vous en SSH sur votre serveur Centreon et aller dans le répertoire des plugins (en fonction de votre supervision):
cd /usr/lib/nagios/plugins
ou
cd /usr/lib/centreon/plugins
ou
cd /usr/lib64/nagios/plugins
Puis, on va créer le fichier:
vi check_ping_down.sh
collez le code ci dessous :
#!/bin/bash
# Xavier BIANCHI - janvier 2019

[ -z $1 ] && echo -e "Retourne une erreur si host en vie"


if ping $1 -w 2 -n -c 2 -q > /dev/null
then
    echo "CRITICAL, IP en cours d'utilisation"
        exit 2
else
    echo "OK , IP non utilisée"
        exit 0
fi

echo $exit

Fermez le fchier (sur VI c’est la commande :wq! ) et donnez les droits d’exécution du script avec :

chmod +x check_ping_down.sh

Vous retrouverez votre script SH dans la liste des plugin de votre centreon lorsque vous allez créer la « Command »

Configuration de la « Command » :

La commande est relativement simple puisque la seule variable qu’il y a lorsque vous allez créer le « service » et l’associer à un « host » ou « hostgroup » est la variable $HOSTADDRESS$ qui correspond à l’adresse IP de l’HOST.

Exemple de résultat lors que l’IP est utilisée :

Chiffrer le Mot de Passe pour la connexion au VCenter via Powercli (Powershell)

Pourquoi ?

La question ne se pose même pas, un mot de passe en clair dans un script, c’est dégueulasse.
Attention : Je ne propose pas non plus la solution ultime en matière de sécurité mais cela restera plus « propre » qu’un mot de passe visible dans le script.

Pré requis :

Le Script :

#Variables
$vcenter = "LE FQDN DE VOTRE VCENTER"
$credfile = ".\credfile2.xml"
$user = Read-Host -Prompt "Nom d'utilisateur, exemple CONSO.ORG\Admin"
$Pass = Read-Host -Prompt "le mot de passe" -AsSecureString
#Génération du fichier
Add-PSSnapIn VMware.VimAutomation.Core
New-VICredentialStoreItem -host $vcenter -user $user -password $Pass -file $credfile

Le principe :

Le script en Powershell va générer un fichier de configuration en XML contenant le login en clair 🙁 mais le mot de passe chiffré.
Le fichier XML se trouvera à l’emplacement du script.

Lors de l’exécution du script, il faudra rentrer le login et mot de passe

Le Fichier XML peut être utilisé lors de votre script nécessitant une connexion au vcenter via la commande
Get-VICredentialStoreItem -file "chemin vers le fichier XML généré"

!!!! Attention, ce fichier XML ne doit être accessible que par vous, ou un compte ayant besoin de lire le fichier, ne négligez pas son stockage !!!!

Lister les Machines Virtuelles comportant des snapshots

Pourquoi ?

Mais Xavier ! Qu’elle est l’intérêt de faire un script qui liste les VM ayant des snapshots, sachant qu’il existe des outils comme RVTOOLS ou des solutions « packagés » comme VeeamONE ?!!!
Réponse :
– Ca coute rien (ou juste du temps)
– On peut planifier le script pour avoir un rapport Hebdo (contrairement à RVTOOL)
– Le PowerShell c’est bien

Pré requis :

Le Script :

#Variables
$vcenter = "LE FQDN DU VCENTER"
#le credfile correspond au fichier XML généré lors du précédent tuto (voir prérequis)
$credfile = ".\credfile.xml"
$creds = Get-VICredentialStoreItem -file $credfile
$smtp = "adresse du SMTP"
$to = "adresse du destinataire"
$from = "vcenter@votredomain.fr"
$subject = "Rapport Hebdo : Liste des serveurs avec snapshots"
$file = ".\snapshot.htm"
$date = Get-Date

#Chargement du module VMWARE
Add-PSSnapin VMware.VimAutomation.Core

#Connexion au vcenter
$creds = Get-VICredentialStoreItem -file $credfile
Connect-VIServer -Server $vcenter -User $creds.User -Password $creds.Password
#Lister les VM et les snapshots
Get-VM | Where-Object { $_.Name -notlike '*.repl*' -and $_.Name -notlike '*_replica*'} | get-snapshot | sort SizeMB | Format-Table vm,name,SizeMB,created | Out-File -FilePath $file
If ((Get-Content $file) -eq $Null) {
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nAucun Snapshot trouve" +  (Get-Content "$file") | Set-Content "$file")
}
else
{
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nCi dessous la liste :" +  (Get-Content "$file") | Set-Content "$file")
}
Add-Content -Path $file -Value "`r` Rapport fait le $date `r`Copyright : Xavier BIANCHI"
$body = Get-Content $file | Out-String
Send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -attachment $file -Body $body -Priority high

Explication du script :

1) Le script se connecte au Vcenter via le fichier credential précédemment généré.
$creds = Get-VICredentialStoreItem -file $credfile
Connect-VIServer -Server $vcenter -User $creds.User -Password $creds.Password
2) Il va lister les VM qui ne comporte pas le sufixe « _repl » « _replica » via cette chaîne :
Get-VM | Where-Object { $_.Name -notlike '*.repl*' -and $_.Name -notlike '*_replica*'}
3) Puis via un pipe, le script va lister les snapshots présent sur cette liste de VM
get-snapshot | sort SizeMB | Format-Table vm,name,SizeMB,created | 
4) Sortie vers un fichier htm :
Out-File -FilePath $file
5) Le fichier de sortie est ensuite analyser afin de voir si il est vide. Si il est vide (donc pas de snapshots), il va écrire dans ce même fichier qu’il n’y a pas de snapshot :
If ((Get-Content $file) -eq $Null) {
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nAucun Snapshot trouve" +  (Get-Content "$file") | Set-Content "$file")
}
6) Si le fichier de sortie n’est pas vide ALORS :
else
{
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nCi dessous la liste :" +  (Get-Content "$file") | Set-Content "$file")
}
7) L’envoi par Email :
Send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -attachment $file -Body $body -Priority high