mardi 2 mars 2021

Grille de données et LiteDB

Dans cet article, nous allons voir comment afficher une collection LiteDB dans un DataGridView. Pour cela, je vais créer une base LiteDB avec une collection. Puis je vais créer un formulaire de type DataGridView pour afficher les données de la collection. J'ajouterons à ce formulaire des fonctions d'ajout, modification et suppression de données.

LiteDB


LiteDB est une base de données "sans serveur" de type NoSQL se présentant sous la forme d'une simple Dll de moins de 500Ko. Elle ne nécessite ni installation, ni droit administrateur. LiteDB est donc facilement portable pour peu que le FrameWork soit installé sur le système.

Site de référence : http://www.litedb.org

Exemple


Dans cette exemple j'utilise LiteDB v3.1.4 (compatible v5.0.10). Pour fonctionner, il faut créer un dossier ldb au même niveau d'arborescence que le script, puis copier dans dossier lbd le fichier LiteDB.dll ainsi que son fichier xml.

 
####################################################################
#
#               Base de données : LiteBD v3.1.4 (compatible v5.0.10)
#                     Powershell.sekki.fr
#
# 1 - Créer un dossier ldb à côté du script.
# 2 - Télécharger et copier LiteDB.dll+xml dans le dossier ldb.
#
####################################################################

#Chemin courant.
$curpath = ""
if ($psISE) { $curpath = split-path -parent $psISE.CurrentFile.Fullpath }
else        { $curpath = Split-Path $MyInvocation.MyCommand.Path  }

#Charge les fonctions LiteDB.
Try   { [void][Reflection.Assembly]::LoadFile($curpath+"\ldb\LiteDB.dll") }
Catch { Write-Host "LiteDB.dll manquant.";Return 2 }

#Version LiteDB.
$global:VersionLDB = ([System.Diagnostics.FileVersionInfo]::GetVersionInfo(($curpath+"\ldb\LiteDB.dll")).FileVersion)[0]
Write-host "Vous utilisez LiteDB v$global:VersionLDB"

#Fonctions personnalisées : Converti le résultat de la query pour l'afficher.
function BsonToObj($bsn)
 {
   #Conversion (compatible LiteDB v3 et v5).
   $obj = New-Object System.Object
   $obj | Add-Member -type NoteProperty -name _id   -Value $bsn["_id"].AsObjectID
   $obj | Add-Member -type NoteProperty -name date  -Value $bsn["date"].AsString
   $obj | Add-Member -type NoteProperty -name info1 -Value $bsn["nom"].AsString
   $obj | Add-Member -type NoteProperty -name info2 -Value $bsn["prix"].AsInt32
   $obj | Add-Member -type NoteProperty -name info3 -Value $bsn["cat"].AsString
   $obj
 }

#Ouvrir/Créer une Base de Données.
$db = New-Object LiteDB.LiteDatabase(($curpath+"\ldb\LiteDB.db"),$null)

#Ouvrir/Créer une Collection.
$global:coll = $db.GetCollection("Info")

#Nouveau document Bson.
$bson = New-Object LiteDB.BsonDocument

#Fonction : Renvoi un nombre entre 0 et 100.
function GR() { Get-Random -minimum 0 -maximum 100 }

#Créer 5 enregistrements si la base est vide.
if (($global:coll.Count([LiteDB.Query]::all())) -eq 0)
  {
    for($i=0;$i -le 4;$i++)
     {
       $x = GR   #Nombre aléatoire entre 0 et 100.
       if ($x -le 50) { $nom = "Sekki";   $prix = $x; $cat = "Z" }
       else           { $nom = "Jumbor";  $prix = $x; $cat = "B" }

       #Ajouter un enregistrement dans la base de données.
       $bson["_id"]  = [LiteDB.ObjectId]::NewObjectId()
       $bson["date"] = date -format "dd/MM/yyyy"
       $bson["nom"]  = [string]$nom
       $bson["prix"] = [int]$prix
       $bson["cat"]  = [string]$cat
       write-host $nom $prix $cat
       [void]$global:coll.Insert($bson)   #Insère le document dans la collection.
     }
 }

#Fonction : Met à jour ou enregistre un objet dans la base (Écriture).
function SaveToBase($obj)
 {
   #Vérification.
   if ([string]::IsNullOrEmpty($obj._id)) { Return }
   
   #Vérifier si c'est un nouvel enregistrement ou une modification.
   if ($obj._id -eq "New") { $modifier = $false } else { $modifier = $true }

   #Création du Bson.
   if ($modifier)
     { #Modifier une ligne existante.
       $bsonid = New-Object LiteDB.ObjectId ([string]($obj._id))
       $bson   = $global:coll.FindOne([LiteDB.Query]::Eq("_id",$bsonid))
     }
   else
     { #Ajouter une nouvelle ligne.
       $bson = New-Object LiteDB.BsonDocument
       $bson["_id"] = [LiteDB.ObjectId]::NewObjectId()
     }
     
   #Tronc commun.   
   $bson["date"] = ([string]$obj.date)
   $bson["nom"]  = ([string]$obj.info1)
   $bson["prix"] = ([int]$obj.info2)
   $bson["cat"]  = ([string]$obj.info3)

   #Enregistrer.
   if ($modifier) { [void]$global:coll.Update($bson) }
   else           { [void]$global:coll.Insert($bson) }
 }

#Initialisation.
$global:delid = @()   #Tableau des lignes à supprimer.

#Formulaire.
$formA = New-Object Windows.Forms.Form
$formA.Text = "DataGridView-LiteDB."
$formA.BackColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
    
#Taille de la fenêtre.
$formA.Size = New-Object Drawing.Point 400,300
$largeurA = $formA.width
$hauteurA = $formA.height
       
#DataGrid.
$DataGridA1 = New-Object System.Windows.Forms.DataGridView
$DataGridA1.Location = New-Object Drawing.Point 6,6
$DataGridA1.Size = New-Object Drawing.Point ($largeurA-28),($hauteurA-78)
$DataGridA1.ReadOnly = $false
$DataGridA1.AutoSize = $false
#$DataGridA1.EditMode = "EditOnEnter"
$DataGridA1.GridColor = "Black"
$DataGridA1.ScrollBars = "Vertical"
$DataGridA1.AllowUserToResizeRows = $true
$DataGridA1.BorderStyle = [System.Windows.Forms.BorderStyle]::None
$DataGridA1.BackgroundColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
$DataGridA1.DefaultCellStyle.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,70,149,218)
 
#Titre/Entête.
$DataGridA1.RowHeadersVisible    = $false
$DataGridA1.ColumnHeadersVisible = $true
$DataGridA1.ColumnHeadersHeightSizeMode = "DisableResizing"
$DataGridA1.EnableHeadersVisualStyles = $false
$DataGridA1.ColumnHeadersDefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(255,70,149,218)
$DataGridA1.ColumnHeadersDefaultCellStyle.ForeColor = "White"
$DataGridA1.ColumnHeadersBorderStyle = "Single"
 
#Colonnes.
[void]$DataGridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$DataGridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$DataGridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$DataGridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$DataGridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
$DataGridA1.Columns[0].Name = "Id"
$DataGridA1.Columns[0].Visible = $false   #Masque la colonne Id.
$DataGridA1.Columns[1].Name = "Date"
$DataGridA1.Columns[2].Name = "Nom"
$DataGridA1.Columns[3].Name = "Prix"
$DataGridA1.Columns[4].Name = "Cat"
 
#Colonnes : Défini la tailles des colonnes.
foreach($column in $DataGridA1.Columns)
 {
   $column.SortMode     = "NotSortable"
   $column.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::Fill
 }
$DataGridA1.Columns[3].Width = 50   #Fixe la taille de la colonne.
$DataGridA1.Columns[4].Width = 50   #Fixe la taille de la colonne.
 
#Events.
$DataGridA1.Add_CellValueChanged({
  $r = $DataGridA1.SelectedCells[0].RowIndex
  $c = $DataGridA1.SelectedCells[0].ColumnIndex
  if ($DataGridA1.Rows[$r].Cells[0].Value -eq $null)
    {
      #Nouvelle ligne : Met la valeur "New" dans la colonne Id.
      #L'Id Bson sera généré plus tard lors de l'enregistrement.
      $DataGridA1.Rows[$DataGridA1.SelectedCells[0].RowIndex].Cells[0].Value="New"
    }
                                })

#Lier.
$formA.Controls.Add($DataGridA1)

#Bouton - Annuler.
$buttonA1 = New-Object Windows.Forms.Button
$buttonA1.Size = New-Object Drawing.Point 80,23
$buttonA1.Location = New-Object Drawing.Point ($largeurA-102),($hauteurA-67)
$buttonA1.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA1.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA1.Text = "Annuler"
$buttonA1.Add_Click({ $formA.Close() })   #Ferme la fenêtre sans enregistrer.
$formA.Controls.Add($buttonA1)
   
#Bouton - Supprimer.
$buttonA2 = New-Object Windows.Forms.Button
$buttonA2.Size = New-Object Drawing.Point 80,23
$buttonA2.Location = New-Object Drawing.Point ($largeurA-188),($hauteurA-67)
$buttonA2.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA2.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA2.Text = "Supprimer"
$buttonA2.Add_Click({
                      #Supprime les lignes sélectionnées.
                      foreach($data in $DataGridA1.SelectedCells)
                       {
                         $r = $data.RowIndex
                         if ($DataGridA1.Rows[$r])
                           {
                             $rowid  = $DataGridA1.Rows[$r].Cells[0].Value
                             #Ajoute l'Id au tableau des lignes à supprimer.
                             $global:delid += $rowid
                             #Supprime la ligne du DataGrid.
                             $DataGridA1.Rows.Remove($DataGridA1.Rows[$r])
                           }
                       }
                   })
$formA.Controls.Add($buttonA2)
 
#Bouton - OK.
$buttonA3 = New-Object Windows.Forms.Button
$buttonA3.Size = New-Object Drawing.Point 80,23
$buttonA3.Location = New-Object Drawing.Point ($largeurA-274),($hauteurA-67)
$buttonA3.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA3.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA3.Text = "OK"
$buttonA3.Add_Click({
                      #Supprimer les données.
                      foreach($rowid in $global:delid)
                       {
                        #Les nouvelles lignes ne sont pas traitées.
                         if ($rowid -ne "New")
                           {
                             #Convertir le String "Id" en Bson "ObjectId".
                             $bsonid = New-Object LiteDB.ObjectId $rowid
                             #Supprime la ligne de la table "Info".
                             switch ($global:VersionLDB)
                              {
                                "3" { $null = $global:coll.Delete([LiteDB.Query]::Eq("_id",$bsonid)) }
                                "5" { $null = $global:coll.DeleteMany([LiteDB.Query]::Eq("_id",$bsonid)) }
                                Default { Write-Host "Version LiteDB non prise en charge !" }
                              }
                           }
                       }

                      #Enregistrer les données.
                      foreach($data in $DataGridA1.Rows)
                       {
                         #Créer un nouvel objet avec les données de la ligne.
                         $savinfo = New-Object PSObject -Property @{ _id = ""; date  = ""; info1 = ""; info2 = 0; info3 = "" }
                         $savinfo._id   = $data.Cells[0].Value
                         $savinfo.date  = $data.Cells[1].Value
                         $savinfo.info1 = $data.Cells[2].Value
                         $savinfo.info2 = $data.Cells[3].Value
                         $savinfo.info3 = $data.Cells[4].Value
                         #Sauvegarder l'objet dans la collection "Info".
                         $null = SaveToBase $savinfo
                       }
                       
                      #Fermer la fenêtre.
                      $formA.Close()
                   })
$formA.Controls.Add($buttonA3)
     
#Event.
$formA.Add_Load({   $DataGridA1.ClearSelection() })
$formA.Add_Resize({
     #Ajuster la position des contrôles lorsque la fenêtre change de taille.
     $largeurA          = $formA.width; $hauteurA = $formA.height
     $DataGridA1.Size   = New-Object Drawing.Point ($largeurA-28),($hauteurA-78)
     $buttonA1.Location = New-Object Drawing.Point ($largeurA-102) ,($hauteurA-67)
     $buttonA2.Location = New-Object Drawing.Point ($largeurA-188),($hauteurA-67)
     $buttonA3.Location = New-Object Drawing.Point ($largeurA-274),($hauteurA-67)
                 })

#Chargement des données.
$base = $global:coll.Find([LiteDB.Query]::all())
foreach($bson in $base)  
 {
   #Ajoute la ligne dans le DataGridView.
   $line = BsonToObj $bson
   [void]$DataGridA1.Rows.Add($line._id, $line.date, $line.info1, $line.info2, $line.info3 )
 }
     
#Afficher.
[void]$formA.ShowDialog()

#Fermer la base de données.
$db.Dispose()

#Fin.

mercredi 10 février 2021

Exécuter un script Powershell à distance

Dans cet article je vais vous présenter la fonction PSSession qui nous permet d’exécuter des commandes Powershell sur des ordinateurs distants. PSSession se base sur le service "Windows Remote Management (WS-Management)". Ce service doit donc être démarré et configurer pour accepter les connections.

Premièrement nous allons voir le mode interactif. Pour cela, nous allons utiliser la commande "Enter-PSSession" qui va nous permettre de taper nos commandes comme si nous étions sur le poste distant.

Enter-PSSession "mycomputer.sekki.fr"

IpConfig

Exit

Ce mode est intéressant mais un peu limité. Pour automatiser mes commandes, je vais avoir besoin d'executer des scripts complet. Pour cela je vais m’intéresser à la commande "New-PSSession" qui me permettra d’exécuter des blocs de commande complet.

 
#Initialisation.
$serveur = "mycomputer.sekki.fr"

#Ouvre une session permanente sur le poste distant.
$mySession = New-PSSession $serveur

if ($mySession)
  {
    #Exécute une commande sur le poste distant.
    Invoke-Command -Session $mySession { Ipconfig }
  }


La commande "Get-PSSession" permet de voir les sessions ouvertes.

Get-PSSession

Au besoin, les sessions peuvent être déconnecte et reconnecté avec les commandes suivantes.

 
#Deconnecter une session.
Disconnect-PSSession $mySession
Get-PSSession


 
#Reconnecter une session.
Connect-PSSession $mysession
Get-PSSession


Pour fermer une session permanente, nous utilisons la commande "Remove-PSSession".

 
#Ferme une session ouverte avec "New-PSSession".
Remove-PSSession $mysession
Get-PSSession



Exemple 1 : Exécuter un script à distance.

 
#Initialisation.
$serveur = "mycomputer.sekki.fr"
#Script à exécuter.
$script = {
            #Script à exécuter sur la session distante.
            Ipconfig
          }

#Ouvre une session sur le poste distant.
$mySession = New-PSSession $serveur
if ($mySession)
  {
    #Exécute le script sur le poste distant.
    Invoke-Command -Session $mySession $script

    #Ferme la session.
    Remove-PSSession $mySession
  }



Exemple 2 : Installer un Msi avec PSSession.

 
#Initialisation.
$serveur = "mycomputer.sekki.fr"
$remoteTemp = "\\"+$serveur+"\C$\temp"

#Copier la source sur le poste distant.
Copy-Item -Path "D:\Sources\Agent.msi" -Destination $remoteTemp

#Ouvre une session sur le poste distant.
$mySession = New-PSSession $serveur
if ($mySession)
  {
    #Exécute le script sur le poste distant.
    Invoke-Command -Session $mySession { Start-Process msiexec -argumentlist "/i C:\temp\agent.msi /qn" }

    #Ferme la session.
    Remove-PSSession $mySession
  }


mercredi 21 octobre 2020

100000 Hits

Le site vient d'atteindre les 100000 hits. Cette année 2020 à connu une hausse significatif du nombre de visite. Les articles les plus visités sont les expressions régulières, les fichiers, les listes déroulantes. Les visiteurs viennent principalement cette année de France, Hong Kong, Etats-Unis. Merci à tous !



lundi 10 août 2020

Alternate Data Stream

Introduction.

Alternate Data Stream (ADS) est un flux de données additionnels lié à un fichier. Habituellement nous utilisons le flux principale pour lire ou écrire un fichier. Avec l'ADS nous pouvons créer des flux de données alternatifs distincts au sein d'un même fichier.

Prenons par exemple, le fichier "test.txt". Ce fichier peut contenir plusieurs textes distincts :
[Test.txt] "Je suis dans le flux principale par défaut."
[Test.txt:Flux1] "Je suis dans le flux 'Flux1'."
[Test.txt:Flux2] "Je suis dans le flux 'Flux2'."

Un peu de pratique pour comprendre tout ça ne fera pas de mal :

  • Lancez la commande "Notepad C:\test.txt", et entrez le texte "Je suis dans le flux principale par défaut.". Si vous ouvrez le fichier depuis l'explorateur vous verrez le texte que vous avez entré.
  • Lancez la commande "Notepad C:\test.txt:Flux1", et entrez le texte "Je suis dans le flux 'Flux1'". Si vous ouvrez le fichier depuis l'explorateur vous ne verrez pas le texte que vous avez entré, mais celui du du flux par défaut. Pour voir le texte du 'Flux1' vous devrez taper de nouveau la commande "Notepad C:\test.txt:Flux1".
  • Lancez la commande "Notepad C:\test.txt:Flux2", et entrez le texte "Je suis dans le flux 'Flux2'". La encore si vous ouvrez le fichier depuis l'explorateur vous ne verrez pas le texte que vous avez entré, mais celui du flux par défaut. Les textes que vous avez tapé dans le Flux1 et dans le Flux2 sont donc "cachés".

Caché ? Peut-être pas tant que ça :

  • Sous DOS, lancez la commande "Dir". Seul le fichier "test.txt" apparait.
  • Sous DOS, lancez la commande "Dir /r". Les flux "teste.txt:Flux1" et "teste.txt:Flux2" liés au fichier "test.txt" apparaissent.

A noter :

  • Les flux alternatifs ne sont possible que sur des partitions formatées en NTFS.
  • La taille des flux ne sont pas comptabilisés dans la taille totale du fichier par défaut. Un fichier de 3Ko dans l'explorateur peut très bien contenir un flux de 10Mo.

Écrire dans un flux alternatif avec Powershell 2.0.


 
#Initialisation.
$fichier = "C:\test.txt"
$flux    = "Flux1"
$cmd     = "cmd.exe"
$Txt     = "Je suis dans le flux 'Flux1'"

#Writing stream.
$arg1 = "/C ""echo $($txt) > $($fichier):$($flux)"""
start-process -filepath $cmd -ArgumentList $arg1

Lire un flux alternatif avec Powershell 2.0.


 
#Initialisation.
$fichier = "C:\test.txt"
$flux    = "Flux1"
$cmd     = "cmd.exe"

#Reading stream.
$arg2 = "/C ""more < $($fichier):$($flux)"""
$info = New-Object System.Diagnostics.ProcessStartInfo
$info.FileName = $cmd
$info.RedirectStandardOutput = $true
$info.UseShellExecute = $false
$info.Arguments = $arg2
$prcs = New-Object System.Diagnostics.Process
$prcs.StartInfo = $info
$null = $prcs.Start()
Sleep -s 1
$stdout = $prcs.StandardOutput.ReadToEnd()
Write-Host $stdout

jeudi 27 février 2020

Annonce - Eco7 v1.5.0

Eco7 version 1.5.0 avec Snmp est enfin sortie. Ca fait un bon moment que j'ai cette version dans mes cartons mais je n'ai pas eu le temps de finaliser totalement sa sortie. C'est chose fait ! Dans cette version j'ai intégré "SharpSnmpLib" ce qui lui permet de récupèrer les compteurs Snmp d'un serveur ou d'un équipement. Eco7 se limite néanmoins à l’interrogation des compteurs Snmp via les OID.

J'ai également apporter quelques amélioration plus discret ici et là. Notamment j'ai réorganisé les champs dans les fenêtres. Plus quelques améliorations de codes.

N'hésitez pas à vous rendre sur la page d'Eco7 pour avoir plus d'informations.

mardi 11 février 2020

Ecriture de l'AD

Nous allons voir dans cet article les commandes pour modifier l'Active Directory. Les commandes de bases sont New-ADUser, Set-ADUser, Remove-ADUser et New-ADGroup, Set-ADGroup, Add-ADGroupMember, Remove-ADGroupMember, Remove-ADGroup. Ces commandes vont nous permettre de modifier les informations sur les utilisateurs et les groupes enregistrés dans l'Active Directory.

Il faut tout d'abord importer les commandes dans notre environnement PowerShell :
 
Import-Module ActiveDirectory

Pour commencer nous allons créer un utilisateur dans l'Active-Directory dans l'OU "Test\Users" :
 
$login    = "Jumbor"   #SamAccountName
$domain   = "sky.fr"
$sbase    = "OU=Users,OU=Test,DC=sky,DC=fr"
$password = ConvertTo-secureString "Password123" -AsPlainText -Force

New-ADUser -Name "Jumbor" -DisplayName "Baru Crow" -UserPrincipalName ($login+"@"+$domain) -SamAccountName $login -AccountPassword $password -ChangePasswordAtLogon $true -Enabled $true -Path $sbase

Pour modifier une propriété du compte, nous allons utiliser la commande suivante :
 
$user = "Jumbor"   #SamAccountName
Set-ADUser -Identity $user -EmailAddress "jumbor@sekki.fr"
Le paramètre "-Identity" accepte plusieurs types d'entrés pour identifier le compte à modifier. Les types acceptés sont "Distinguished Name","SID/GUID","SamAccountName", ou un objet utilisateur.

De nombreuses propriétés peuvent être modifiées de cette façon. Par exemple  : -AccountExpirationDate, -CannotChangePassword, -ChangePasswordAtLogon, -PasswordNeverExpires,-Description, -GivenName, -HomeDirectory, -LogonWorkstations, -Organization, -PostalCode, -ScriptPath, -StreetAddress, -City ...

Mais parfois, nous devons modifier un attribue qui ne figure pas dans la liste des paramètres. Dans ce cas nous utilisons les commandes "-Replace", "-Clear", "-Add", "-Remove" pour modifier un ou plusieurs attribues :
 
$user = "Jumbor"   #SamAccountName
Set-ADUser -Identity $user -Replace @{loginShell="/ksh/bash"}

Pour supprimer un utilisateur :
 
$user = "Jumbor"   #SamAccountName
Remove-ADUser -Identity $user -Confirm:$false

Nous allons maintenant créer un groupe dans l'Active-Directory dans l'OU "Test\Groups" :
 
$group = "One_Shot"   #SamAccountName
$sbase    = "OU=Groups,OU=Test,DC=sky,DC=fr"

New-ADGroup -Name "One Shot" -SamAccountName $group -GroupScope "Global" -GroupCategory "Security" -Path $sbase
GroupScope prend les valeurs suivantes : DomainLocal, Global, Universal.
GroupCategory prend les valeurs suivantes : Distribution, Security.

Pour modifier une propriété du groupe, nous allons utiliser la commande suivante :
 
$group = "One_Shot"   #SamAccountName
Set-ADGroup -Identity $group -Description "One Shot Group !"

Pour modifier un attribue :
 
$group = "One_Shot"   #SamAccountName
Set-ADGroup -Identity $group -Replace @{mail="Jumbor@sekki.fr"}

Pour ajouter des membres dans le groupe :
 
$group = "One_Shot"   #SamAccountName
Add-ADGroupMember -Identity $group -Members "Jumbor","Arkel"

Pour supprimer des membres du groupe :
 
$group = "One_Shot"   #SamAccountName
Remove-ADGroupMember -Identity $group -Members "Jumbor","Arkel" -Confirm:$false

Pour supprimer un groupe :
 
$group = "One_Shot"   #SamAccountName
Remove-ADGroup -Identity $group -Confirm:$false