簡體   English   中英

AD組比較 - PowerShell

[英]AD group comparison - PowerShell

使用以下功能(比較2個用戶的組成員資格)時,我得到的結果沒有意義。

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
}

當我調用它(Compare-ADUserGroups User1 User2)時,我得到一個類似於以下的結果集:

  • CN = [所有用戶],OU = adm,DC = OSUMC,DC = EDU <=
  • CN = [所有用戶],OU = adm,DC = OSUMC,DC = EDU =>
  • CN =擴展用戶,OU = MSG,DC = OSUMC,DC = EDU <=
  • CN =擴展用戶,OU = MSG,DC = OSUMC,DC = EDU =>
  • CN = LCS2005,OU =分布列表,DC = OSUMC,DC = EDU <=
  • CN = LCS2005,OU =分布列表,DC = OSUMC,DC = EDU =>

鑒於它們是相同的並且我沒有使用-IncludeEqual參數,我希望這些不顯示。 有關為何出現這些問題的任何想法?

我編寫了一個用戶界面來比較組並在兩個用戶之間應用更改 在此輸入圖像描述

#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 'Script@mydomain.com' -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

它們中的某些東西正在放棄比較。 如果你跑的話,你會看到類似的東西......

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

因為這些對象的某些屬性(例如VM和PM)會在兩個Get-Process運行之間的短暫間隔中發生變化。 因此,您可能遇到類似的情況,兩個對象之間的某些屬性不同。 默認情況下,Compare-Object會查看每個屬性。

另一種方法是使用Compare-Object的-property參數來比較特定屬性,而不是比較整個對象。 在這方面,Compare-Object肯定有點棘手,因為它使用對象屬性而不是簡單地處理文本。

我最好的猜測是Get-QADUser提供的MemberOf屬性可能返回一個對象而不僅僅是作為字符串的組的可分辨名稱。 以下是我用於比較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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM