2008-12-08 15 views
3

Lorsque vous utilisez la fonction suivante (comparez l'appartenance à deux groupes d'utilisateurs), j'obtiens des résultats qui n'ont aucun sens.Comparaison de groupes AD - PowerShell

function Compare-ADUserGroups <br> 
{ #requires -pssnapin Quest.ActiveRoles.ADManagement 
    param (
     [string] $FirstUser = $(Throw "logonname required."), 
     [string] $SecondUser = $(Throw "logonname required.") 
    ) 

    $a = (Get-QADUser $FirstUser).MemberOf 
    $b = (Get-QADUser $SecondUser).MemberOf 
    $c = Compare-Object -referenceObject $a -differenceObject $b 
    $c | Sort-Object InputObject 
} 

Quand j'appelle cela (Comparez-ADUserGroups Utilisateur1 Utilisateur2), je reçois un jeu de résultats similaire à ce qui suit:

  • CN = [Tous les utilisateurs], OU = adm, DC = OSUMC, DC = EDU < =
  • CN = [Tous les utilisateurs], OU = adm, DC = OSUMC, DC = EDU =>
  • CN = utilisateurs étendus, OU = MSG, DC = OSUMC, DC = EDU < =
  • CN = Utilisateurs étendus, OU = MSG, DC = OSUMC, DC = EDU =>
  • CN = LCS2005, OU = Listes de distribution, DC = OSUMC, DC = EDU < =
  • CN = LCS2005, OU = Listes de distribution, DC = OSUMC, DC = EDU =>

j'attendre ceux-ci n'apparaissent pas étant donné qu'ils sont égaux et que je n'utilise pas le paramètre -IncludeEqual. Des idées sur la raison pour laquelle elles apparaissent?

Répondre

1

Il ya quelque chose dans ceux qui se débarrasse de la comparaison. Vous verrez quelque chose de similaire si vous courez ...

get-process | export-clixml c \ procs.xml Diff (get-process) (import-clixml c: \ procs.xml)

Parce que QUELQUES propriétés de ces objets - des choses comme VM et PM, par exemple, changent dans le bref intervalle entre les deux exécutions Get-Process. Il est donc possible que vous rencontriez quelque chose de similaire, où certaines propriétés diffèrent entre les deux objets. Par défaut, Compare-Object recherche chaque propriété.

Une alternative consiste à utiliser le paramètre -property de Compare-Object pour comparer uniquement des propriétés spécifiques, plutôt que de comparer l'objet entier. Compare-Object peut certainement être un peu délicat à cet égard, à cause de la façon dont il fonctionne avec les propriétés de l'objet plutôt que de simplement travailler avec du texte.

1

J'écris une interface utilisateur pour comparer des groupes et appliquer le changement entre les 2 utilisateurs enter image description here

#requires -version 2 
<# 
    .SYNOPSIS 
     Compare les groupe entre 2 users 
    .DESCRIPTION 
     Affiche sur 2 colones les les groupes AD des 2 users a comparer et met en evidance les goupes mamquants de chaque user 
    .PARAMETER user1 
     Nom complet de l'utilisateur 1 a comparer 
     ex : domain.adds\UserName 
    .PARAMETER user2 
     Nom complet de l'utilisateur 2 a comparer 
    .EXAMPLE 
     .\Compare-QadUsersGrp.ps1 $(whoami) $($UserNames) 
    .EXAMPLE 
     Start-Process -WindowStyle hidden powershell -ArgumentList "-WindowStyle Normal .\Compare-QadUsersGrp.ps1 $(whoami) $($UserNames)" 
#> 


param( 
    [string]$SessionName1 = 'Domain\testalb', 
    [string]$SessionName2 = 'Domain\testalb2' 
) 

$currentRunner = $false 
$version = '0.60' 
$source = "Script Compare-Sessions (alopez)" 
$lanStorage = "c:" 

    add-content "$lanStorage\Get-TSAdmin_Usage-Log.txt" -value "[$(Get-Date -Format 'yyyy/MM/dd HH:mm:ss')] $(whoami) - $($version) Compare-Sessions - $SessionName1 vs $SessionName2" 

############################################### Zone liée a l'affichage (refresh) ################################################ 

    function Refresh-Tabs { 
     $loadBar.Visible = $true 
     $loadBar.Value = 0 

     $ListCompared = Get-vsGrps 

     $loadBar.Value = 90 
     $SrvForm.height = 178 + $ListCompared.count * 22 

     $DefaultColor = 'DarkBlue' 
     Set-DataGridView -DataGridView $Grille -AlternativeRowColor -ForeColor $DefaultColor -BackColor 'AliceBlue' 

     Load-DataGridView -DataGridView $Grille -Item (ConvertTo-DataTable -InputObject ($ListCompared | ?{$_})) 
     $Grille.Columns["$SessionName2"].Width=320 
     $Grille.Columns["$SessionName2"].HeaderCell.Style.Alignment = 'MiddleRight' 
     #$Grille.Columns["$SessionName2"].AutoSizeMode = $true 
     $Grille.Columns["$SessionName2"].DefaultCellStyle.Alignment = 'MiddleRight' 
     $Grille.Columns['#'].Width=20 
     $Grille.Columns["$SessionName1"].Width=330 
     #$Grille.Columns["$SessionName2"].AutoSizeMode = $true 

     $Grille.Columns['DN'].Width = 0 
     Find-DataGridViewValue -DataGridView $Grille -Value '==' -FindingColumns '#' -RowForeColor Gray 
     Find-DataGridViewValue -DataGridView $Grille -Value '=>' -FindingColumns '#' -RowForeColor Green 
     #Find-DataGridViewValue -DataGridView $Grille -Value '<=' -FindingColumns '#' -RowForeColor Blue 

     $loadBar.Value = 100 
     $loadBar.Visible = $false 

    } 

    function Set-DataGridView { 
     PARAM (
      [ValidateNotNull()] 
      [Parameter(Mandatory = $true)] 
      [System.Windows.Forms.DataGridView]$DataGridView, 

      [Parameter(ParameterSetName = "AlternativeRowColor")] 
      [Switch]$AlternativeRowColor, 

      [Parameter(Mandatory = $true, ParameterSetName = "AlternativeRowColor")] 
      [System.Drawing.Color]$ForeColor, 

      [Parameter(Mandatory = $true, ParameterSetName = "AlternativeRowColor")] 
      [System.Drawing.Color]$BackColor, 

      [Parameter(ParameterSetName = "Proper")] 
      [Switch]$ProperFormat 
     ) 
     PROCESS 
     { 

      $DataGridView.DefaultCellStyle.ForeColor = $DefaultColor 

      if ($psboundparameters['AlternativeRowColor']) { # les ligne PAIRES 
       $DataGridView.AlternatingRowsDefaultCellStyle.ForeColor = $ForeColor 
       $DataGridView.AlternatingRowsDefaultCellStyle.BackColor = $BackColor 
      } 


      if ($psboundparameters['ProperFormat']) { 
       #$Font = New-Object -TypeName System.Drawing.Font -ArgumentList "Segoi UI", 10 
       $Font = New-Object -TypeName System.Drawing.Font -ArgumentList "Consolas", 10 
       #[System.Drawing.FontStyle]::Bold 

       $DataGridView.ColumnHeadersBorderStyle = 'Raised' 
       $DataGridView.BorderStyle = 'Fixed3D' 
       $DataGridView.SelectionMode = 'FullRowSelect' 
       $DataGridView.AllowUserToResizeRows = $false 
       $datagridview.DefaultCellStyle.font = $Font 
      } 
     } 
    } 

    function ConvertTo-DataTable { 
     <# 
      .SYNOPSIS 
       Converts objects into a DataTable. 
      .DESCRIPTION 
       Converts objects into a DataTable, which are used for DataBinding. 
      .PARAMETER InputObject 
       The input to convert into a DataTable. 
      .PARAMETER Table 
       The DataTable you wish to load the input into. 
      .PARAMETER RetainColumns 
       This switch tells the function to keep the DataTable's existing columns. 
      .PARAMETER FilterWMIProperties 
       This switch removes WMI properties that start with an underline. 
      .EXAMPLE 
       $DataTable = ConvertTo-DataTable -InputObject (Get-Process) 
     #> 
     [OutputType([System.Data.DataTable])] 
     param(
      [ValidateNotNull()] 
       $InputObject, 
      [ValidateNotNull()] 
       [System.Data.DataTable] 
        $Table, 
      [switch] $RetainColumns, 
      [switch] $FilterWMIProperties 
     ) 

     if($Table -eq $null) { 
      $Table = New-Object System.Data.DataTable 
     } 

     if($InputObject-is [System.Data.DataTable]) { 
      $Table = $InputObject 
     } else { 
      if(-not $RetainColumns -or $Table.Columns.Count -eq 0) { 
       #Clear out the Table Contents 
       $Table.Clear() 

       if($InputObject -eq $null){ return } #Empty Data 

       $object = $null 
       #find the first non null value 
       foreach($item in $InputObject) { 
        if($item -ne $null) { 
         $object = $item 
         break 
        } 
       } 

       if($object -eq $null) { return } #All null then empty 

       #Get all the properties in order to create the columns 
       foreach ($prop in $object.PSObject.Get_Properties()) { 
        if(-not $FilterWMIProperties -or -not $prop.Name.StartsWith('__')) #filter out WMI properties 
        { 
         #Get the type from the Definition string 
         $type = $null 

         if($prop.Value -ne $null) { 
          try{ $type = $prop.Value.GetType() } catch {} 
         } 

         if($type -ne $null) # -and [System.Type]::GetTypeCode($type) -ne 'Object') 
         { 
          [void]$table.Columns.Add($prop.Name, $type) 
         } 
         else #Type info not found 
         { 
          [void]$table.Columns.Add($prop.Name)  
         } 
        } 
       } 

       if($object -is [System.Data.DataRow]) { 
        foreach($item in $InputObject) { 
         $Table.Rows.Add($item) 
        } 
        return @(,$Table) 
       } 
      } else { 
       $Table.Rows.Clear() 
      } 

      foreach($item in $InputObject) {  
       $row = $table.NewRow() 

       if($item) { 
        foreach ($prop in $item.PSObject.Get_Properties()) { 
         if($table.Columns.Contains($prop.Name)) { 
          $row.Item($prop.Name) = $prop.Value 
         } 
        } 
       } 
       [void]$table.Rows.Add($row) 
      } 
     } 

     return @(,$Table) 
    } 

    function Load-DataGridView { 
     <# 
      .SYNOPSIS 
       This functions helps you load items into a DataGridView. 
      .DESCRIPTION 
       Use this function to dynamically load items into the DataGridView control. 
      .PARAMETER DataGridView 
       The ComboBox control you want to add items to. 
      .PARAMETER Item 
       The object or objects you wish to load into the ComboBox's items collection. 
      .PARAMETER DataMember 
       Sets the name of the list or table in the data source for which the DataGridView is displaying data. 
     #> 
     Param (
      [ValidateNotNull()] 
       [Parameter(Mandatory=$true)] 
        [System.Windows.Forms.DataGridView] 
         $DataGridView, 
      [ValidateNotNull()] 
       [Parameter(Mandatory=$true)] 
        $Item, 
      [Parameter(Mandatory=$false)] 
       [string] 
        $DataMember 
     ) 
     $DataGridView.SuspendLayout() 
     $DataGridView.DataMember = $DataMember 

     if ($Item -is [System.ComponentModel.IListSource] -or $Item -is [System.ComponentModel.IBindingList] -or $Item -is [System.ComponentModel.IBindingListView]) { 
      $DataGridView.DataSource = $Item 
     } else { 
      $array = New-Object System.Collections.ArrayList 

      if ($Item -is [System.Collections.IList]) { 
       $array.AddRange($Item) 
      } else { 
       $array.Add($Item) 
      } 
      $DataGridView.DataSource = $array 
     } 
     $DataGridView.ResumeLayout() 
    } 

    function Find-DataGridViewValue { 
     # https://github.com/lazywinadmin/WinFormPS/blob/master/WinFormPS.psm1 
     <# 
      .SYNOPSIS 
       The Find-DataGridViewValue function helps you to find a specific value and select the cell, row or to set a fore and back color. 

      .DESCRIPTION 
       The Find-DataGridViewValue function helps you to find a specific value and select the cell, row or to set a fore and back color. 

      .PARAMETER DataGridView 
       Specifies the DataGridView Control to use 

      .PARAMETER RowBackColor 
       Specifies the back color of the row to use 

      .PARAMETER RowForeColor 
       Specifies the fore color of the row to use 

      .PARAMETER SelectCell 
       Specifies to select only the cell when the value is found 

      .PARAMETER SelectRow 
       Specifies to select the entire row when the value is found 

      .PARAMETER FindingColumns 
       Specifies the column(s) to search Value or NotValue 

      .PARAMETER Value 
       Specifies the value to search 

      .PARAMETER NotValue 
       Specifies the value to not match in all column (param FindingColumns is recomanded) 

      .EXAMPLE 
       PS C:\> Find-DataGridViewValue -DataGridView $Grille -Value $textbox1.Text 

       This will find the value and select the cell(s) 

      .EXAMPLE 
       PS C:\> Find-DataGridViewValue -DataGridView $Grille -Value $textbox1.Text -RowForeColor 'Red' -RowBackColor 'Black' 

       This will find the value and color the fore and back of the row 
      .EXAMPLE 
       PS C:\> Find-DataGridViewValue -DataGridView $Grille -Value $textbox1.Text -SelectRow 

       This will find the value and select the entire row 

      .NOTES 
       Francois-Xavier Cat 
       @lazywinadm 
       www.lazywinadmin.com 
     #> 
     [CmdletBinding(DefaultParameterSetName = "Cell")] 
     PARAM (
      [ValidateNotNull()] 
      [Parameter(Mandatory = $true)] 
      [System.Windows.Forms.DataGridView]$DataGridView, 
      $Value, 
      $NotValue, 
      [string[]]$FindingColumns, 
      #[Parameter(ParameterSetName = "Cell")] 
      [Switch]$SelectCell, 
      #[Parameter(ParameterSetName = "Row")] 
      [Switch]$SelectRow, 
      #[Parameter(ParameterSetName = "Column")] 
      #[Switch]$SelectColumn, 
      [Parameter(ParameterSetName = "RowColor")] 
      [system.Drawing.Color]$RowForeColor, 
      [Parameter(ParameterSetName = "RowColor")] 
      [system.Drawing.Color]$RowBackColor 
     ) 

     PROCESS 
     { 
      $DataGridView.ClearSelection() 
      ForEach ($Col in $DataGridView.Columns) { 
       if ($FindingColumns -contains $Col.Name -or !$FindingColumns) { 
        ForEach ($Row in $DataGridView.Rows) { 
         $CurrentCell = $dataGridView.Rows[$Row.index].Cells[$Col.index] 

         if ((-not $CurrentCell.Value.Equals([DBNull]::Value)) -and (($Value -and ($CurrentCell.Value.ToString() -like "$Value")) -or ($NotValue -and ($CurrentCell.Value.ToString() -notlike "$NotValue")))) 
         { 
          # Append-RichtextboxStatus -ComputerName $textboxSocieteName.Text -Source "Find $Value$NotValue" -Message "Colonne:$($col.name) ligne:$($row.index)" 
          # Row Selection 
          IF ($PSBoundParameters['SelectRow']) 
          { 
           $dataGridView.Rows[$Row.index].Selected = $true 
          } 

          # Row Fore Color 
          IF ($PSBoundParameters['RowForeColor']) 
          { 
           $dataGridView.Rows[$Row.index].DefaultCellStyle.ForeColor = $RowForeColor 
          } 

          # Row Back Color 
          IF ($PSBoundParameters['RowBackColor']) 
          { 
           $dataGridView.Rows[$Row.index].DefaultCellStyle.BackColor = $RowBackColor 
          } 
          # Cell Selection 
          ELSEIF (-not ($PSBoundParameters['SelectRow']) -and -not ($PSBoundParameters['RowForeColor']) -and -not ($PSBoundParameters['SelectColumn'])) 
          { 
           $CurrentCell.Selected = $true 
          } 
         }#IF not empty and contains value 
        } 
       } 
      } 
     }#PROCESS 
    } 
############################################### Zone liée aux actions sur les objects ############################################ 

    $CommonObject = [hashtable]::Synchronized(@{ 
    }) 

    function Get-vsGrps { 
     Add-PSSnapin 'Quest.ActiveRoles.ADManagement' 

     $loadBar.Value = 10 
     $User1 = Get-QADUser -identity $SessionName1 
     $loadBar.Value = 20 
     $User2 = Get-QADUser -identity $SessionName2 
     $loadBar.Value = 30 
     $ListCompared = Compare-Object $User1.memberof $User2.memberof -IncludeEqual | %{ 
      #$_.InputObject=(Get-QADGroup $_.InputObject).Name 
      #$_.InputObject = ($_.InputObject -split(','))[0] -replace('CN=','') 
      [pscustomobject][ordered]@{ 
       "$SessionName2" = $(
        if ($_.SideIndicator -eq '==' -or $_.SideIndicator -eq '=>') { 
         ($_.InputObject -split(','))[0] -replace('CN=','') 
        } else { 
         '' 
        } 
       ) 
       '#' = $_.SideIndicator 
       "$SessionName1" = $(
        if ($_.SideIndicator -eq '==' -or $_.SideIndicator -eq '<=') { 
         ($_.InputObject -split(','))[0] -replace('CN=','') 
        } else { 
         '' 
        } 
       ) 
       DN = $_.InputObject 
      } 
     } | Sort-Object DN 
     $loadBar.Value = 40 
     $ListCompared 
    } 

    function Toggle-Group { 
     $loadBar.Value = 0 
     $loadBar.Visible = $true 
     $loadBar.Value = 50 

     $line = $Grille.CurrentCell.RowIndex 
     $col = $Grille.CurrentCell.ColumnIndex 
     $DN = $Grille.currentrow.Cells[3].value 
     $Grp = ($DN -split(','))[0] -replace('CN=','') 

     if (@(0,2) -contains $col -and $edit.Checked) { 
      $user = $Grille.columns[$Col].HeaderText 
      if ($Grille.CurrentCell.value -eq '' -or $Grille.CurrentCell.value -like " Supp ($Grp) ! ") { 
       add-QADGroupMember -identity $DN -member $user 
       retour-email -title "$user : Add '$Grp'" -msg "Add $DN" 
       $Grille.CurrentCell.value = " Add ($Grp) ! " 
       $Grille.CurrentCell.Style.ForeColor = 'Magenta' 
      } 
      else { 
       Remove-QADGroupMember -identity $DN -member $user 
       retour-email -title "$user : Supp '$Grp'" -msg "Supp $DN" 
       $Grille.CurrentCell.value = " Supp ($Grp) ! " 
       $Grille.CurrentCell.Style.ForeColor = 'Red' 
      } 
      $Grille.currentrow.Cells[1].value = "><" 
      $Grille.currentrow.Cells[1].style.ForeColor = 'Red' 
     } 

     $loadBar.Value = 100 
     $loadBar.Visible = $false 
    } 

    function retour-email { 
     param (
      [string] $email = $script:currentRunner, 
      [switch] $force = $edit.Checked, 
      [string] $title = '.', 
      [string] $msg = '.' 
     ) 
     if ($email -and $force) { 
      Send-MailMessage -To $email -from '[email protected]' -Subject "$title" -SmtpServer mySmtpServer -BodyAsHtml -Body "$msg" 
     } 
     add-content "$lanStorage\Get-TSAdmin_Usage-Log.txt" -value "[$(Get-Date -Format 'yyyy/MM/dd HH:mm:ss')] $(whoami) - $($version) Compare-Sessions - $title" 
    } 


############################################### Zone GUI/Interface - formulaire ############################################### 

#requires -version 2 

Add-Type -AssemblyName 'System.Drawing' 
Add-Type -AssemblyName 'System.Windows.Forms' 
[System.Windows.Forms.Application]::EnableVisualStyles() 

# permet de faire les requette serveur apres ouverture du formulaire 
    $timerOnload = New-Object System.Windows.Forms.Timer 
    $timerOnload.Interval = 500 
    $timerOnload.add_Tick({ 
      Refresh-Tabs 

      $script:currentRunner = (whoami | Get-QADUser).email 

      $edit.Text = "Edit Mode, with email return ($($script:currentRunner))" 
      $timerOnload.Enabled = $false 
     }) 
    $timerOnload.Enabled = $true 
    $timerOnload.Start() 
# 

#region $SrvForm 
$SrvForm = New-Object -TypeName 'System.Windows.Forms.Form' 
$SrvForm.Name = 'SrvForm' 
$SrvForm.MaximumSize = New-Object -TypeName 'System.Drawing.Size' -ArgumentList @(0, 1200) 
$SrvForm.MinimumSize = New-Object -TypeName 'System.Drawing.Size' -ArgumentList @(670, 180) 
$SrvForm.Size = New-Object -TypeName 'System.Drawing.Size' -ArgumentList @(670, 350) 
$SrvForm.Padding = New-Object -TypeName 'System.Windows.Forms.Padding' -ArgumentList @(1,1,1,0) 
$SrvForm.KeyPreview = $True 
$SrvForm.Add_KeyDown({ if ($_.KeyCode -eq 'Escape') {$SrvForm.Close()} }) 
$SrvForm.Add_KeyDown({ if ($_.KeyCode -eq 'F5') { 
      Refresh-Tabs 
     } 
    }) 
$icon1 = & { 
    $iconString = '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' 
    $iconStream = New-Object -TypeName 'System.IO.MemoryStream' -ArgumentList @(,([System.Convert]::FromBase64String($iconString))) 
    $icon = New-Object -TypeName 'System.Drawing.Icon' -ArgumentList $iconStream 
    $iconStream.Dispose() 
    return $icon 
} 
$SrvForm.text = "$SessionName2 vs $SessionName1" 
$SrvForm.Icon = $icon1 
$SrvForm.Topmost = $True 
$SrvForm.Topmost = $false 

$SrvForm.SuspendLayout() 

    #region $groupBox1 
    $groupBox1 = New-Object -TypeName 'System.Windows.Forms.GroupBox' 
    $groupBox1.Text = 'Comparatif des groupes (direct)' 
    $groupBox1.Dock = [System.Windows.Forms.DockStyle]::Fill 
    $groupBox1.SuspendLayout() 

     #region $Grille 
     $Grille = New-Object -TypeName 'System.Windows.Forms.DataGridView' 
     $Grille.Name = 'Grille' 
     $Grille.Dock = [System.Windows.Forms.DockStyle]::Fill 
     $Grille.ReadOnly = $true 
     $Grille.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect 
     $Grille.RowHeadersVisible = $false 
     $Grille.AllowUserToAddRows = $false 
     $Grille.AllowUserToResizeRows = $false 
     $Grille.AllowUserToDeleteRows = $false 
     $Grille.PerformLayout() 

     #endregion $Grille 

     [System.Void]$groupBox1.Controls.Add($Grille) 

     #region $aide 
     $aide = New-Object -TypeName 'System.Windows.Forms.Label' 
     $aide.Name = 'aide' 
     $aide.Text = 'Double-click sur un groupe ajoute ou supprime le groupe pour cet utilisateurs' 
     $aide.Visible = $false 
     $aide.ForeColor = [System.Drawing.Color]::Red 
     $aide.Dock = [System.Windows.Forms.DockStyle]::Bottom 
     $aide.TextAlign = [System.Drawing.ContentAlignment]::MiddleRight 
     #endregion $aide 

     [System.Void]$groupBox1.Controls.Add($aide) 

    $groupBox1.ResumeLayout($false) 
    $groupBox1.PerformLayout() 
    #endregion $groupBox1 

    [System.Void]$SrvForm.Controls.Add($groupBox1) 

    #region $panel1 
    $panel1 = New-Object -TypeName 'System.Windows.Forms.Panel' 
    $panel1.Size = New-Object -TypeName 'System.Drawing.Size' -ArgumentList @(0, 30) 
    $panel1.Padding = New-Object -TypeName 'System.Windows.Forms.Padding' -ArgumentList @(4) 
    $panel1.Dock = [System.Windows.Forms.DockStyle]::Bottom 
    $panel1.SuspendLayout() 

     #region $edit 
     $edit = New-Object -TypeName 'System.Windows.Forms.CheckBox' 
     $edit.Name = 'edit' 
     $edit.Text = 'Mode Edition, avec retour par email de chaque modif' 
     $edit.Checked = $false 
     $edit.Width = 480 
     $edit.Dock = [System.Windows.Forms.DockStyle]::Left 
     #endregion $edit 

     [System.Void]$panel1.Controls.Add($edit) 

     #region $button1 
     $button1 = New-Object -TypeName 'System.Windows.Forms.Button' 
     $button1.Text = 'Retour Email complet' 
     $button1.Width = 150 
     $button1.Dock = [System.Windows.Forms.DockStyle]::Right 
     #endregion $button1 

     [System.Void]$panel1.Controls.Add($button1) 

    $panel1.ResumeLayout($false) 
    $panel1.PerformLayout() 
    #endregion $panel1 

    [System.Void]$SrvForm.Controls.Add($panel1) 

    #region $statusStrip1 
    $statusStrip1 = New-Object -TypeName 'System.Windows.Forms.StatusStrip' 
    $statusStrip1.SuspendLayout() 

     #region $LabelVersion 
     $LabelVersion = New-Object -TypeName 'System.Windows.Forms.ToolStripStatusLabel' 
     $LabelVersion.Text = 'V0.00' 
     $LabelVersion.Spring = $true 
     $LabelVersion.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft 
     #endregion $LabelVersion 

     [System.Void]$statusStrip1.Items.Add($LabelVersion) 

     #region $loadBar 
     $loadBar = New-Object -TypeName 'System.Windows.Forms.ToolStripProgressBar' 
     $loadBar.Style = [System.Windows.Forms.ProgressBarStyle]::Continuous 
     $loadBar.Value = 100 
     $loadBar.Visible = $true 
     #endregion $loadBar 

     [System.Void]$statusStrip1.Items.Add($loadBar) 

    $statusStrip1.ResumeLayout($false) 
    $statusStrip1.PerformLayout() 
    #endregion $statusStrip1 

    [System.Void]$SrvForm.Controls.Add($statusStrip1) 

############################################### Zone personalisation du formilaire ############################################## 

$LabelVersion.Text = "[PID:$pid] $($script:MyInvocation.MyCommand) - V $Version" 

$button1.add_click({ 
     retour-email -title "$SessionName2 vs $SessionName1" -msg (Get-vsGrps | ConvertTo-Html) 
    }) 

$Grille.add_DoubleClick({ 
     Toggle-group 
    }) 

$Grille.add_ColumnHeaderMouseClick({ 
     Find-DataGridViewValue -DataGridView $Grille -Value '==' -FindingColumns '#' -RowForeColor Gray 
     Find-DataGridViewValue -DataGridView $Grille -Value '=>' -FindingColumns '#' -RowForeColor Green 
    }) 

$edit.Add_CheckStateChanged({ 
     $aide.visible = $edit.Checked 
    }) 

$SrvForm.ResumeLayout($false) 
$SrvForm.PerformLayout() 
#endregion $SrvForm 

#region GUI Startup 
$SrvForm.ShowDialog() 
#endregion GUI Startup 

#$powershell.Dispose() 
#$runspace.close() 
$timerOnload.stop() 

Get-vsGrps 
0

Ma meilleure estimation est que la propriété MemberOf fournie par Get-QADUser est probablement retourne un objet au lieu de simplement le nom unique de le groupe comme une chaîne. Voici le script que j'utilise pour comparer les appartenances au groupe Active Directory:

# Compare the group memberships of 2 Active Directory Users or the user memberships of 2 Active Directory Groups. 
# Requires the ActiveDirectory PowerShell module from the Microsoft's Remote Server Administration Tools. 

Import-Module ActiveDirectory 

function Get-ComparisonResult ($name1, $name2, $sideIndicator) 
{ 
    $comparisonResult = $null 

    switch ($_.SideIndicator) 
    { 
     '<=' { $comparisonResult = "$($name1) Only" } 
     '==' { $comparisonResult = "$($name1) and $($name2)" } 
     '=>' { $comparisonResult = "$($name2) Only" } 
    } 

    return $comparisonResult 
} 

function Compare-ADUserGroupMembership($userName1, $userName2) 
{ 
    $userComparisonResultColumn = @{ name = 'Comparison Result'; expression = { Get-ComparisonResult $user1.DisplayName $user2.DisplayName $_.SideIndicator } } 
    $groupNameColumn = @{ name = 'Group Name'; expression = { (Get-ADGroup $_.InputObject).Name } } 

    $user1 = Get-ADUser $userName1 -Properties memberOf, displayName 
    $user2 = Get-ADUser $userName2 -Properties memberOf, displayName 

    $userGroupComparison = Compare-Object -IncludeEqual $user1.MemberOf $user2.MemberOf | Select $userComparisonResultColumn, $groupNameColumn 

    return $userGroupComparison 
} 

function Compare-ADGroupMembership($groupName1, $groupName2) 
{ 
    $groupComparisonResultColumn = @{ name = 'Comparison Result'; expression = { Get-ComparisonResult $groupName1 $groupName2 $_.SideIndicator } } 
    $userNameColumn = @{ name = 'User Name'; expression = { $_.InputObject.name } } 

    $groupMembers1 = Get-ADGroupMember $groupName1 
    $groupMembers2 = Get-ADGroupMember $groupName2 

    $groupMemberComparison = Compare-Object -IncludeEqual $groupMembers1 $groupMembers2 | Select $groupComparisonResultColumn, $userNameColumn 

    return $groupMemberComparison 
} 

Compare-ADUserGroupMembership 'userone' 'usertwo' | ft -AutoSize 
Compare-ADGroupMembership 'Group One' 'Group Two' | ft -AutoSize 
Questions connexes