Le Powershell est un langage orienté objet pour les produits microsoft. Il est plus puissant que l'invite de commande standard.
Il permet d'effectuer toutes sortes de tache pouvant être répétitive (comme la création d'utilisateurs Active Directory) beaucoup plus rapidement qu'en utilisant l'interface graphique.
Le Powershell fonctionne sur la base de mots-clé. Voici la liste des principaux mots-clé :
Add
permet d’ajouter des données ou informations sur le nom qui le suit ;Get
permet d’obtenir des données ou informations sur le nom qui le suit ;Read
permet de lire des données ou informations sur le nom qui le suit ;Clear
permet de réinitialiser l’affichage de l’interface ;Import
et Export
permettent d’importer/exporter des fichiers de commande ou des Alias ;New
permet de créer de nouveaux objets ou variables ;Set
permet de définir des données ou informations sur le nom qui le suit ;Write
permet de d’écrire des données ou informations sur le nom qui le suit et peut agir comme le compte rendu d’une commande.Get-Help
Powershell n'est pas sensible à la case, contrairement aux commandes et scripts Linux
$var=
Read-Host
$val = Read-Host "Saisir une phrase"
#Saisie une phrase: phrase de test !
$var
[string]
: chaîne de caractères, on l’a déjà vu précédemment ;[char]
: caractère Unicode sur 16 bits ;[byte]
: caractère sur 8 bits non signé ;[int]
: valeur entière sur 32 bits signée ;[long]
: valeur entière sur 64 bits signée ;[bool]
: valeur booléenne (True/False : vraie/fausse) ;[decimal]
: valeur décimal sur 128 bits ;[DateTime]
: Date et heure ;[array]
: tableau de valeurs.Get-Location
(ou l'alias pwd
connu sous Linux)Get-ChildItem
(ou l'alias ls
ou dir
)#Créer une répertoire :
New-Item -Name "Nom_Rep" -ItemType Directory
#Créer un fichier :
New-Item -Name "nom_fichier.ext" -ItemType File
#Créer un fichier avec du contenu :
New-Item -Name "nom_fichier.ext" -ItemType File -Value "Contenu"
#Copier
Copy-Item -Path chemin_fichier_a_copier -Destination chemin_destination
#Déplacer
Move-Item -Path chemin_fichier_a_deplacer -Destination répertoire_destination
#Renommer
Rename-Item -Path fichier_à_renommer -NewName chemin_absolu_fichier_renommé
#Supprimer
Remove-Item Chemin_fichier
Lorsque nous voulons copier de façon récursive le contenu d'un répertoire, il faut utiliser l'option
-Recurse
.
Il faut utiliser le caractère \ et non / sous linux.
Cela se passe en 3 étapes :
# 1ère étape : Création du répertoire
New-Item -Name "Dossier_partagé" -ItemType Directory
# 2ème étape : Définition du partage + droits :
New-SmbShare -Name "Nom_Partage" -Path "Chemin_absolu_repertoire_a_partager" -FullAccess Everyone
Nous mettons un accès à tout le monde. Il s'agit ici d'une bonne pratique Microsoft. Nous mettrons les "vraies" permissions dans l'onglet "Sécurité", ou plus tard en Powershell grâce aux ACLs.
Attention : Il faut obligatoirement indiquer le chemin absolu (c'est à dire C:\...\nom_dossier) et non le chemin relatif (.\nom_dossier) sinon la commande ne fonctionnera pas !
Si vous suivez les bonnes pratiques Microsoft, ce qui suit ne vous servira pas. On ne définie pas les permissions sur les partages (onglet partage), mais directement sur les ressources (onglet sécurité).
Le mot clé pour modifier un partage est Grant-SmbShareAccess
.
Exemple :
Grant-SmbShareAccess -Name Sauvegarde -AccountName "Tout le Monde" -AccessRight Read
La valeur pour l'option "AccessRight" peut être :
Full
: Contrôle totalChange
: Droit d'écritureRead
: Droit de lectureCustom
: PersonnaliséGet-SmbShareAccess
, avec éventuellement le paramètre -Name <nom du partage>
pour ne voir qu'un partage en particulier.Nous pouvons vérifier le fonctionnement du partage avec la commande Get-ChildItem \\Serveur\nom_partage
.
Nous pouvons utiliser le paramètre
-Force
pour afficher les dossiers cachés (équivaut àls -a
sous Linux)
Pour créer un utilisateur, la commande à utiliser est New-ADUser
. Il faut cependant un certain nombre d'informations, tel que le login, le mot de passe, ...
Syntaxe création d'un utilisateur :
New-ADUser -Name "NOM Prénom" -SamAccountName <Login> -UserPrincipalName "login@domaine" -AccountPassword (ConvertTo-SecureString -AsPlainText <mdp> -Force) -PasswordNeverExpires $true -CannotChangePassword $true
-Name
: Indique le nom du compte, généralement le nom/prénom de la personne;-SamAccountName
: Indique le Login de la personne, ce qu'elle va utiliser pour se connecter;-UserPrincipalName
: Indique le nom complet de l'utilisateur dans l'AD (format login@domaine);-AccountPassword
: Renseigne le mot de passe. l'option ConvertTo-SecureString
permet de convertir le mot de passe en clair dans un format chiffré, illisible par l'humain.-PasswordNeverExpires
: Indique si l'on veut que les personnes changent leurs mot de passe à intervalle régulier.Pour se faire la main avec Active Directory, mieux vaut activer cette option. En production, il vaut mieux désactiver cette option.
-CannotChangePassword
: Indique si l'on autorise le changement du mot de passe directement par les utilisateurs.Cette option dépend de la politique interne de l'entreprise, et dépendera probablement du service auquel cette personne sera affectée.
On active ensuite ce compte :
Enable-ADAccount <login>
Nous pouvons également ajouter l'option
-Enable $true
dans la commande précédente pour activer le compte
On peut lister les utilisateurs Active Directory avec la commande Get-ADUser -Filter *
. Cette commande va renvoyer TOUTES les informations de l'utilisateur, ce qui n'est peut-être pas nécessaire. Nous pouvons donc sélectionner les champs que l'on veut récupérer.
Exemple :
Get-ADUser -Filter * | select Name, samAccountName, UserPrincipalName
Cette commande va récupérer les champs nom, login et nom complet de l'utilisateur sur l'AD.
Nous pouvons également exporter les champs sélectionnés dans un fichier CSV en ajoutant la commande | Export-Csv <nom_sortie.csv -Encoding UTF8
.
Attention : le | est important, puis que nous ajoutons cette commande à la suite de la précédente
La syntaxe principale sera New-ADGroup <nom_groupe> -GroupScope <Politique groupe>
Les politiques disponibles sont :
Global
: Groupe répandu sur toute la forêt de l'AD (exemple : groupe comptabilité, direction, ...)...
Il faut maintenant ajouter les utilisateurs aux groupes :
Add-ADGroupMember -identity $groupe -Members $nom
Par défaut, PowerShell est configuré en mode "Restricted", ce qui ne permet pas d'executer de script . Il faut changer ce mode d'execution pour pouvoir utiliser nos scripts.
Get-ExecutionPolicy
: Afficher politique appliquéeSet-ExecutionPolicy
<nom_politique> : Changer le mode d'executionVoici la liste des différents modes d'execution :
Restricted
: aucun script ne peut être exécuté. PowerShell est utilisable uniquement en mode interactif.AllSigned
: seuls les scripts signés peuvent être exécutés.RemoteSigned
: les scripts téléchargés depuis Internet doivent être signés pour être exécutés. Les scripts présents sur votre poste de travail ne sont pas concernés et peuvent être exécutés.Unrestricted
: pas de restrictions. Les scripts peuvent être exécutés.Attention : Nous allons passer notre mode d'execution en mode
Unrestricted
afin de simplifier l'apprentissage. Mais dans un environnement de production, il faut proteger l'execution car Powershell est très puissant. Il faut choisir le modeAllSigned
ouRemoteSigned
, ou plus restrictifRestricted
. Mais en aucun cas cela doit être enUnrestricted
Il peut être interessant de créer un script pour automatiser la création d'objets ActiveDirectory. Pour cela, il faut nous connecter au serveur AD dans le script.
$connexion = New-Object System.DirectoryServices.DirectoryEntry('LDAP://<ip_machine>/DC=<domain>,DC=<domain2>','login','mot de passe')
Nous voulons maintenant rechercher certaines informations de notre AD. Pour cela, il va falloir créer plusieurs objets. Cela va se faire en 3 étapes :
DirectorySearcher
pour lister tout le contenu de l'AD;$nom_objet_precedent.Filter
;# On se connecte à l'AD
$dom = New-Object System.DirectoryServices.DirectoryEntry('LDAP://192.168.68.5/DC=whitecyber,DC=corp','lotdevot','Azerty123/')
# On récupère le contenu
$domSearch = New-object System.DirectoryServices.DirectorySearcher($dom)
#On filtre
$domSearch.Filter = '(objectCategory=container)'
#On limite le niveau du filtrage
$domSearch.SearchScope = 'OneLevel'
# Nous pouvons remplacer OneLevel par SubTree pour la récursivité
#On Lance la recherche
$domSearch.FindAll()
On obtient alors :
Les étapes sont similaire à l'étape précédente, à quelques variations près :
# On se connecte à l'AD
$uo = New-Object System.DirectoryServices.DirectoryEntry('LDAP://192.168.68.5/OU=Utilisateurs,DC=whitecyber,DC=corp','lotdevot','Azerty123/')
# On récupère le contenu
$uoSearch = New-object System.DirectoryServices.DirectorySearcher($uo)
#On filtre
$uoSearch.Filter = '(ou=Direction)'
#On limite le niveau du filtrage
$uoSearch.SearchScope = 'SubTree'
#On Lance la recherche
$uoSearch.FindAll()
# On se connecte à l'AD
$uo = New-Object System.DirectoryServices.DirectoryEntry('LDAP://192.168.68.5/OU=Utilisateurs,DC=whitecyber,DC=corp','lotdevot','Azerty123/')
$nouvelleOU = $uo.create('organizationalUnit','ou=test')
$nouvelleOU.put('description','TP PWS et LDAP')
$nouvelleOU.setinfo()
Set-Location path
- Move to directory [Alias: cd]Get-ChildItem path
- List contents of a folder [Alias: gci, dir, ls]New-Item name
- Create file [Alias: ni]New-Item name
-ItemType Directory - Create directory [Alias: ni]Rename-Item name
newname - Rename a file or directory [Alias: ren, rni]Remove-Item name
- Delete a file or directory [Alias: del, erase, rm, rmdir, ri, rd]Copy-Item name newname
- Copy a file or folder [Alias: cp, copy, cpi]Move-Item name newfolder
- Move a file or folder [Alias: mi, move, mv]Get-Content name
- Show contents of a file [Alias: gc]Get-Service
- List all services [Alias: gsv]Get-Service name
- Get details about a specific service [Alias: gsv]Start-Service name
- Start a stopped service [Alias: sasv]Stop-Service name
- Stop a running service [Alias: spsv]Restart-Service name
- Restart a running serviceGet-Process
- List all processes [Alias: ps]Get-Process name
- Get details about a specific process [Alias: ps]Start-Process name
- Start a new process [Alias: start, saps]Stop-Process name
- Stop a process [Alias: kill, spps]Wait-Process name
- Wait for a process to stop before continuingDebug-Process name
- Attach a debugger to a processGet-NetIPConfiguration
- Show local interfaces and their assigned IPsTest-Connection name
- Basic pingTest-NetConnection name
- Advanced pingTest-NetConnection name -TraceRoute
- Perform a trace routeTest-NetConnection name -Port port
- Perform a port checkSet-DnsClientServerAddress -InterfaceAlias interface -ServerAddresses dns,dns2
- Change DNS serversResolve-DnsName name
- Basic DNS lookupResolve-DnsName name -Type recordtype
- DNS lookup for a specific record (ie txt, srv, soa, etc)Clear-DnsClientCache
- Clear the local DNS cacheEnable-PSRemoting
- Enable PowerShell remoting locallyEnter-PSSession computername -Credential username
- Connect to a remote computerInvoke-Command -ComputerName computername -ScriptBlock {commands to execute} -Credential username
- Execute the script block contents on the remote computer$SessionName = New-PSSession computername -Credential username
- Store a persistent session in a variable which can be used with Enter-PSSession or Invoke-CommandRestart-Computer
- Reboot machineStop-Computer
- Shutdown machineCheckpoint-Computer
- Create a system restore pointRestore-Computer
- Restore computer to a checkpointGet-ComputerInfo
- Large amount of system info (win ver, edition, bios version, etc)$PSVersionTable
- Show PowerShell versionGet-WMIObject Win32_OperatingSystem
- Show Windows version$env:COMPUTERNAME
- Show computer nameTo check a condition in a script or function, use an If statement. The If can check many types of conditions, including the value of variables and the properties of objects.
if (<Condition>) {
# Perform action
}
elseif (<Condition>) {
# Perform action
}
else {
# Perform action
}
To check multiple conditions, use a Switch statement. The Switch statement is equivalent to a series of If statements, but it is simpler. The Switch statement lists each condition and an optional action. If a condition obtains, the action is performed.
switch (<Variable>) {
'value1' { # Actions }
'value2' { # Actions }
'value3' { # Actions }
Default { # Actions }
}
The Foreach statement (also known as a Foreach loop) is a language construct for stepping through (iterating) a series of values in a collection of items. The simplest and most typical type of collection to traverse is an array. Within a Foreach loop, it is common to run one or more commands against each item in an array.
foreach (<Item> in <Collection>) {
# Perform Action
}
The For statement (also known as a For loop) is a language construct you can use to create a loop that runs commands in a command block while a specified condition evaluates to true.
for (<Int>; <Condition>; <Repeat>) {
# Perform Action
}
Runs a statement list one or more times, subject to a While or Until condition.
do {
# Perform Action
} until (<Collection>)
do {
# Perform Action
} while (<Collection>)
Use Try, Catch, and Finally blocks to respond to or handle terminating errors in scripts.
try {
# Action
}
catch {
# Catch terminating errors
}
finally {
# Performed whether success or error
}
A function is a named block of code that performs an action. When you type the function name, the code in the function runs.
function (<Parameters>) {
# Actions
}
A filter is a named block of code that establishes conditions for an action. You can type the name of the filter in place of the condition, such as in a Where-Object command.
filter (<Parameters>) {
# Actions
}
ipcsv Chemin_Fichier_CSV -Delimiter "Délimiteur"
ipcsv Chemin_Fichier_CSV -Delimiter "Délimiteur" | format-table
ipcsv Chemin_Fichier_CSV -Delimiter "Délimiteur" | ? {$_.nom_colonne_csv -match Ce_que_l'on_veut_filtrer} | format-table