PI Services

Le blog des collaborateurs de PI Services

Importation d’un fichier type csv dans un fichier excel en powershell

 

Nous allons ici convertir un fichier csv en fichier excel en powershell.

Nous allons pour cela nous servir des objets COM fournit lors de l’installation de excel :

Initialisons notre variable

$Excel = New-Object -ComObject excel.application

Maintenant nous allons rendre visible chaque étapes effectué par nos lignes de commandes dans Excel.

$Excel.visible = $true

Une fenêtre Excel s’est ouverte

image 

Nous importons notre fichier type csv (séparation par des virgules)

$csv=import-csv "C:\Users\ato\Downloads\export.txt" -header site,ptr

image

Maintenant, nous ajoutons un nouveau classeur

$workbook = $Excel.workbooks.add()

image

Nous allons maintenant rajouter les en têtes de nos colonnes dans le fichier excel

$excel.cells.item(1,1) = "site"

$excel.cells.item(1,2) = "PTR"

On peut voir apparaitre les valeurs dans notre fichier excel

image

On définit notre compteur à 2 permettant d'ajouter les valeurs de notre csv dans les colonnes site et ptr précédemment ajouté.

$i=2

On va maintenant récupérer les valeurs de notre fichier type csv et les ajouter a notre fichier excel

foreach  ($s in $csv)
{
    $excel.cells.item($i,1)=$s.site
    $excel.cells.item($i,2) = $s.ptr
    $i++
}

image

Récupération d’attributs utilisateurs dans un tableau en powershell

 

Dans cet exemple nous allons voir comment récupérer l’UPN, le SAN et le profilepath des utilisateurs d’un groupe dans l’ad courant que nous allons ensuite placer dans un tableau.

Tout d’abord, connectons nous au domaine courant et indexons notre variable de recherche

$domain=[ADSI]''
$search=New-Object system.directoryservices.directorysearcher($domain)

Maintenant, nous allons nous connecter au groupe sur lequel nous allons récupérer les membres

$GRP= "GroupTest"
$search.filter="(&(objectClass=Group)(name=$GRP))"
$group=$search.findone()

Initialisons notre variable contenant notre tableau

$tab=@()

Maintenant pour chaque membres du groupe, nous récupérons à tour de rôle dans des variables l’upn, le profilepath et le SamAccountName.

foreach ($user in $group.properties.member)
{
    $searchUser=New-Object system.directoryservices.directorysearcher($domain)
    $searchUser.filter="(&(objectclass=user)(distinguishedname=$user))"
    $Upn=$SearchUser.findone().properties.userprincipalname
    $profilepath=$SearchUser.findone().properties.profilepath
    $sam=$SearchUser.findone().properties.samaccountname
}

 

Pour chacune des valeurs récupérés, nous allons les placer dans un tableau.

Pour créer un tableau, nous allons initier un objet de type PsObject dans une variable

$line=new-object psobject

Ensuite, il suffit d’ajouter à cette variable un membre contenant le nom de notre tableau et la valeur

Ajout colonne UPN

$line | Add-Member -Name UPN -MemberType NoteProperty -Value ""

image

Ajout colonne SAN

$line | Add-Member -Name SAN -MemberType NoteProperty -Value ""

image 

Ajout colonne ProfilePath

$line | Add-Member -Name ProfilePath -MemberType NoteProperty -Value ""

image

Pour finir, nous ajoutons notre variable $line à notre variable tableau $tab

$tab+=$line

image

 

Maintenant nous allons compléter le contenu de notre boucle afin que chacune des valeurs récupérés soit placé dans notre tableau

foreach ($user in $group.properties.member)
{
    $line=new-object psobject; $user="$user"
    $searchUser=New-Object system.directoryservices.directorysearcher($domain)
    $searchUser.filter="(&(objectclass=user)(distinguishedname=$user))"
    $Upn=$SearchUser.findone().properties.userprincipalname
    $profilepath=$SearchUser.findone().properties.profilepath
    $sam=$SearchUser.findone().properties.samaccountname
   $line | Add-Member -Name UPN -MemberType NoteProperty -Value"$upn"
    $line | Add-Member -Name SamAccountName -MemberType NoteProperty -Value "$sam"
    $line | Add-Member -Name ProfilePath -MemberType NoteProperty -Value "$profilepath"
    $tab+=$line

}

Ce qui donne :

image

Remettre via le registre le chemin par défaut de l’ost sous Outook 2007

 

Après une migration du profil utilisateur,si la valeur de l’emplacement de l’ost sous Outlook 2007 empêche l’ouverture du client de messagerie, celle ci peut être remis par défaut via le registre.

Pour cela, il faut supprimer l’entrée 001f6610 dans la clé suivante :

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\%username%\13dbb0c8aa05101a9bb000aa002fc45a

Une fois celle ci supprimée, le client Outlook régénèrera son OST dans l’emplacement par défaut.

Exemple pour exclure cette clé en utilisant USMT.

<unconditionalExclude>

<objectSet>        

<pattern type="Registry">HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\*\13dbb0c8aa05101a9bb000aa002fc45a [001f6610]</pattern>
          

</objectSet>
</unconditionalExclude>

Utilisation des Windows forms .Net via Powershell sous WinPE 4

Depuis WinPe 4, il est possible d’utiliser des forms issues du .net via Powershell.

Pour cela, il faut rajouter à votre image wim des packages issues de l’adk.

Monter tout d’abord votre image wim

imagex64.exe /mountrw c:\winpe4_x86\media\sources\boot.wim 1 c:\winpe4_x86\mount

clip_image002

clip_image003

Installation du 1er Package: Netfx4

dism /image:c:\winpe4_x86\mount /add-package /packagepath:"C:\Program Files (x86)\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\WinPE_OCs\winpe-netfx4.cab"

clip_image005

Installation du 2nd Package: Powershell3

dism /image:c:\winpe4_x86\mount /add-package /packagepath:"C:\Program Files (x86)\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\WinPE_OCs\winpe-powershell3.cab"

clip_image007

Une fois ceux ci installé, démonté votre image wim.

imagex64.exe /unmount c:\winpe4_x86\mount /commit

Démarrer maintenant sur votre PE.

clip_image009

Et là, nous allons lancer un exemple de script ps1 faisant appel à une interface graphique apporté par le Framework .NET.

clip_image011

Nous pouvons donc imaginer en remplacement du HTA, une interface faisant appel aux Forms pour l’élaboration d’un Master par exemple.

Client http sous Powershell

A l’image de Wget qui est un client http, nous pouvons faire appel en powershell à un objet qui permettra donc d’effectuer des requêtes depuis des Urls. Pour cela, il faut utiliser un objet particulier : system.net.webclient

Regardons maintenant certaines propriétés qu’il propose :

(new-object system.net.webclient) | gm

clip_image001

Maintenant, imaginons que nous disposons d’une Url nous retournant un résultat formaté en fichier type csv (séparateur : virgule) nous renvoyant des informations que nous désirons récupérés dans nos scripts, il suffit pour cela de télécharger via la méthode DownloadFile les informations dans un fichier. Et ensuite d’importer ce fichier dans une variable.

Exemple:

$client=new-object system.net.webclient

$url="http://AppelUrl.local"

$path="c:\test\DataUrl.txt"

$client.DownloadFile ($url, $path)

$csv=Import-Csv $path -header intitulé,Process

clip_image002

A partir de là, nous pouvons facilement exploiter les données reçues par l’url.

Récupérer les paramètres Firefox quel que soit la version par USMT

Vous souhaitez récupérer via l’outil USMT les favoris Firefox.

Cependant depuis quelques temps, le nombre de versions de Firefox a augmenté de façon importante.

Pour supporter l’ensemble des versions de Firefox, ouvrez donc le fichier xml MigApp de USMT.

Identifiez la partie consacrée à Firefox

<!-- Mozilla Firefox 3 -->

<component context="UserAndSystem" type="Application">

<displayName _locID="migapp.firefox3">Mozilla Firefox</displayName>

<environment name="GlobalEnv"/>

<environment name="GlobalEnvX64"/>

<role role="Settings">

<detection>

<conditions>

<condition>MigXmlHelper.DoesObjectExist("Registry","%HklmWowSoftware%\Mozilla\Mozilla Firefox 3.*\bin [PathToExe]")</condition>

</conditions>

</detection>

<rules context="User">

<destinationCleanup>

<objectSet>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\*\Cache\* [*]</pattern>

</objectSet>

</destinationCleanup>

<include>

<objectSet>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\* [*]</pattern>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\* [*]</pattern>

</objectSet>

</include>

<exclude>

<objectSet>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\Crash Reports\* [*]</pattern>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\Profiles\*\ [pluginreg.dat]</pattern>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\*\Cache\* [*]</pattern>

</objectSet>

</exclude>

<merge script="MigXmlHelper.SourcePriority()">

<objectSet>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\* [*]</pattern>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\* [*]</pattern>

</objectSet>

</merge>

</rules>

</role>

</component>

Pour supporter l’ensemble des versions de Firefox, il suffit de modifier un seul caractère correspondant à la version par le caractere « * » à la ligne correspondant à :

<condition>MigXmlHelper.DoesObjectExist("Registry","%HklmWowSoftware%\Mozilla\Mozilla Firefox 3.*\bin [PathToExe]")</condition>

Exemple :

<!-- Mozilla Firefox -->

<component context="UserAndSystem" type="Application">

<displayName _locID="migapp.firefox3">Mozilla Firefox</displayName>

<environment name="GlobalEnv"/>

<environment name="GlobalEnvX64"/>

<role role="Settings">

<detection>

<conditions>

<condition>MigXmlHelper.DoesObjectExist("Registry","%HklmWowSoftware%\Mozilla\Mozilla Firefox *.*\bin [PathToExe]")</condition>

</conditions>

</detection>

<rules context="User">

<destinationCleanup>

<objectSet>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\*\Cache\* [*]</pattern>

</objectSet>

</destinationCleanup>

<include>

<objectSet>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\* [*]</pattern>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\* [*]</pattern>

</objectSet>

</include>

<exclude>

<objectSet>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\Crash Reports\* [*]</pattern>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\Profiles\*\ [pluginreg.dat]</pattern>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\*\Cache\* [*]</pattern>

</objectSet>

</exclude>

<merge script="MigXmlHelper.SourcePriority()">

<objectSet>

<pattern type="File">%CSIDL_APPDATA%\Mozilla\Firefox\* [*]</pattern>

<pattern type="File">%CSIDL_LOCAL_APPDATA%\Mozilla\Firefox\Profiles\* [*]</pattern>

</objectSet>

</merge>

</rules>

</role>

</component>

Mettre la langue du clavier Fr dans WinPe

Pour définir nativement la langue Française dans votre Windows PE, il est nécessaire de modifier le registre du PE.

Pour cela, nous allons monter notre image boot.wim correspondant à notre WinPe.

clip_image001

imagex64.exe /mountrw c:\winpe4_x86\media\sources\boot.wim 1 c:\winpe4_x86\mount

clip_image003

clip_image004

Une fois celui-ci monté, nous allons monter le fichier de ruche Default

clip_image005

clip_image006

clip_image007

clip_image008

Ensuite, il nous suffit de modifier la valeur de la sous clé 1 dans

HKEY_CURRENT_USER\WinPe\Keyboard Layout\Preload

clip_image010

Et de lui saisir la valeur correspondante au Français

clip_image011

clip_image012

clip_image001[5]

Décharger la ruche, démonter l’image et rebooter sur votre PE.

Le clavier sera désormais en Français.

Suppression d’un profil utilisateur sous Windows 7 manuellement

Sous Windows XP, beaucoup de personnes pour résoudre des problèmes de profils renomment les profils utilisateurs(.old) afin que celui-ci soit régénéré par le système lors de la connexion de l’utilisateur en question.

Cependant sous Windows 7, pour régénérer un profil utilisateur en utilisant la technique de renommage, celui-ci va générer un profil temporaire.

Exemple : je me logue avec un utilisateur.

image

On peut désormais constater le répertoire du profil utilisateur dans c:\users.

clip_image002

Maintenant, on se connecte en tant que administrateur sur la machine et on renomme le répertoire du profil utilisateur afin que celui-ci ne soit plus trouver par le système.

clip_image003

Maintenant, si notre utilisateur essaie de se reconnecter sur cette même machine, il va avoir la surprise d’utiliser un profil temporaire.

clip_image004

clip_image005

La méthode pour régénérer un profil utilisateur en renommant le répertoire doit également contenir la suppression du pointeur du profil dans le registre.

Pour cela, il suffit d’accéder à la clé ProfileList

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

Et là on peut constater que notre répertoire utilisateur n’étant plus trouvé par le système, celui s’est renommé .bak

clip_image006

clip_image007

Il faut alors supprimer cette clé.

clip_image008

clip_image009

Dès lors ou l’utilisateur se reconnectera à sa machine celui-ci régénéra un profil et non plus un profil temporaire.

L’entrée de l’utilisateur dans la clé “ProfileList” est également régénéré.

 

clip_image010

Erreur de démarrage du client Outlook à cause du complément Symantec Antivirus

Vous avez ce message d’erreur lorsque vous ouvrez Outlook.

clip_image002

Cela peut être dû à une mauvaise désinstallation de logiciels qui avait ajouté une extension dans Outlook.

Pour résoudre le problème, vous devez aller dans votre profil dans les données applicatives locales de Outlook : %userprofile%\appdata\local\Microsoft\Outlook et de supprimer ou renommer le fichier extend.dat en extend.dat.bak

Relancez Outlook.

L’erreur n’apparaitra plus.

Préparation et déploiement d’un VHD contenant une image de référence dans Hyper-V3 en powershell

Dans ce blog, nous allons voir comment préparer un VHD étapes par étapes en appliquant notre image de référence Windows 8 pour un serveur sous Hyper-v.

Il est intéressant de connaitre les cmdlets sous Powershell étant donné que l’utilisation de Diskpart est maintenant dépréciée.

Notre serveur Hyper-v ne détient actuellement aucune machine.

clip_image002

Nous définissons dans une variable le nom qu’aura notre VM dans Hyper-v

$NameVm="Demo"

Nous définissons dans une variable l’emplacement et le nom qu’aura notre VHD créé

$PathVM="C:\VHD\$NameVM.vhdx"

Nous créons maintenant notre VHD à l’aide de la cmdlet " new-vm " qui créera directement la VM dans Hyper-v .

new-vm -Name $NameVm -MemoryStartupBytes 1024MB -NewVHDPath $PathVM -NewVHDSizeBytes 10000MB

Le résultat :

clip_image003

clip_image004

clip_image005

Il est maintenant nécessaire que nous montions notre VHD pour le préparer (partionnement, boot,..)

Mount-VHD $PathVM

En utilisant maintenant la cmdlet "Get-disk" nous pouvons vérifier que notre VHD à correctement été monté.

clip_image007

Notre VHD n’ayant pas encore été partitionné, il apparait sous le style de partition raw. Nous allons maintenant récupérer le numéro de partition de ce VHD grâce au « Friendly Name » et au « Partition Style »

$numero=(get-disk | Where-Object {$_.friendlyname -match "virtual" -and $_.partitionstyle -match "raw"}).number

Il faut maintenant initialisé le VHD afin de pouvoir formater celui-ci et y stocker des données.

Initialize-Disk $numero -PartitionStyle mbr

get-disk $numero

clip_image009

Le disque a bien été initialisé.

Nous allons maintenant partitionner ce VHD en NTFS

$Label="Demo"

New-Partition $numero -UseMaximumSize -AssignDriveLetter | Format-Volume -NewFileSystemLabel $label -FileSystem NTFS –asjob

Nous ne connaissons pas la lettre de volume qui lui a été alloué. Pour cela, on peut consulter tous les volumes à l’aide de la cmdlet :

Get-volume

clip_image011

Nous allons maintenant récupérer notre volume par l’identifiant de notre label précédemment définit.

$vol=(Get-Volume | Where-Object {$_.filesystemlabel -match $label}).driveletter

$vol1=$vol+":"

Et maintenant nous appliquons notre master de référence sous l’extension WIM avec DISM.

dism /apply-image /imagefile:C:\Users\administrateur\Desktop\Master_8.wim /index:1 /applydir:$vol1

clip_image012

On définit maintenant la partition comme étant active pour que celle-ci puisse booter depuis un OS.

Set-Partition -DriveLetter $vol -IsActive $true

Et maintenant nous allons configurer notre magasin BCD en lui ajoutant l’entrée de notre nouveau disque VHD.

$vol2=$vol1+"\Windows"

bcdboot $vol2 /s $vol1

clip_image013

Nous pouvons maintenant démonter notre VHD puis démarrer notre VM.

Dismount-VHD $PathVM

Start-VM $NameVm

Maintenant si nous revenons sur la console Hyper-v, nous pouvons constater que notre VM a bien démarrer et que notre master de référence Works !!

clip_image015

Il suffit maintenant d’imaginer un déploiement de master de référence à plus grande échelle pour une phase de recette par exemple.

Pour cela, il suffit d’effectuer une boucle dans un script avec toute les cmdlets et cela se déploiera au sein de Hyper-v de façon automatisé.