首页 > 解决方案 > 如何过滤 Powershell 以将目录名称与 AD SamAccountName 进行比较并忽略 .Vx 模式?

问题描述

我的 AD 用户帐户的格式类似于First.Last name (SamAccountName)。用户 HomeDirectory 漫游配置文件以某种方式获得了额外的版本控制,如下所示:

\\FileServer\RoamingProfiles\UserData$\User10.Name.V1
\\FileServer\RoamingProfiles\UserData$\User28.Name.V2
\\FileServer\RoamingProfiles\UserData$\User6.Name.V3
\\FileServer\RoamingProfiles\UserData$\User3.Name.V3.old
\\FileServer\RoamingProfiles\UserData$\User23.Name.V6
\\FileServer\RoamingProfiles\UserData$\User81.Name.V8.OLD
\\FileServer\RoamingProfiles\UserData$\User61.Name.V9
\\FileServer\RoamingProfiles\UserData$\User73.Name.V12
\\FileServer\RoamingProfiles\UserData$\User33.Name.V5
\\FileServer\RoamingProfiles\UserData$\User74.Name.V2
\\FileServer\RoamingProfiles\UserData$\First.LastName.RENAME

如何修改下面的 Powershell 脚本以仅从上面的目录列表中获取First.Last name (SamAccountName) 模式?

$ServerHomeDirShare = "\\FileServer\RoamingProfiles\UserData$\"
$filter = "(Enabled -eq 'true')"

# get all user accounts from AD; only SamAccountName required
$users = Get-ADUser -Filter $filter | Select-Object -ExpandProperty SamAccountName

# foreach directory in \\server\share check if it has a corresponding ad user
Get-ChildItem -Path $ServerHomeDirShare -Directory |
Select-Object -Property `
              Name,
              @{ n = 'AD User Exist'; e = { $users -contains $_.Name } },
              FullName,
              @{ n = 'LastAccessTime'; e = { $_.LastAccessTime.ToString('yyyy-MM-dd HH:mm:ss') } },
              @{ n = "Directory Size (MB)"; e = {
                    Try
                    {
                        $Path = $_.FullName
                        $Size = ((Get-ChildItem -Path $Path -ErrorAction Stop).Length).Sum/1MB
                        [math]::Round($Size, 2)
                    }
                    Catch
                    {
                        "ERROR: $($_.Exception.Message)"
                    }
                }} |
Where-Object { -not $_.'AD User Exist' } |
Export-Csv -NoTypeInformation -Path C:\UserProfilesNotExist-Size.csv

因此可以将其与 AD 数据库进行比较,以分离孤立的主目录。

标签: regexpowershellscriptingactive-directorywindows-scripting

解决方案


您可以-replace在目录名称上使用正则表达式来仅获取Firstname.Lastname部分,跳过.Vxand .RENAME(or .WhatEver)

接下来,为了计算目录大小,我假设您想要总大小,包括子文件夹中的内容,所以我也会更改该方法:

$ServerHomeDirShare = '\\FileServer\RoamingProfiles\UserData$'
$filter = "(Enabled -eq 'true')"

# get all user accounts from AD; only SamAccountName required
$users = Get-ADUser -Filter $filter | Select-Object -ExpandProperty SamAccountName

# foreach directory in \\server\share check if it has a corresponding ad user
# user SamAccountNames are in format 'FirstName.Lastname', so we need to cut off
# any versioning postfixex from the directory names in order to compare
Get-ChildItem -Path $ServerHomeDirShare -Directory |
Select-Object -Property Name,
              @{ n = 'AD User Exist'; e = { $users -contains ($_.Name -replace '^(\w+\.\w+).*', '$1') } },
              FullName,
              @{ n = 'LastAccessTime'; e = { $_.LastAccessTime.ToString('yyyy-MM-dd HH:mm:ss') } },
              @{ n = "Directory Size (MB)"; e = {
                        Try {
                            $Size = (Get-ChildItem -Path $_.FullName -Recurse -ErrorAction Stop | 
                                     Measure-Object Length -Sum).Sum / 1MB
                            [math]::Round($Size, 2)
                        }
                        Catch {
                            "ERROR: $($_.Exception.Message)"
                        }
                    }
                } |
Where-Object { -not $_.'AD User Exist' } |
Export-Csv -NoTypeInformation -Path C:\UserProfilesNotExist-Size.csv

另一种方法是只过滤那些名称在 $users 数组中找不到的目录,而不是之后。在这种情况下,您不需要列“AD 用户存在”,因为您知道这些是孤立的用户文件夹。

Get-ChildItem -Path $ServerHomeDirShare -Directory | 
Where-Object { $users -notcontains ($_.Name -replace '^(\w+\.\w+).*', '$1') } |
Select-Object -Property Name, FullName,
              @{ n = 'LastAccessTime'; e = { $_.LastAccessTime.ToString('yyyy-MM-dd HH:mm:ss') } },
              @{ n = "Directory Size (MB)"; e = {
                        Try {
                            $Size = (Get-ChildItem -Path $_.FullName -Recurse -ErrorAction Stop | 
                                     Measure-Object Length -Sum).Sum / 1MB
                            [math]::Round($Size, 2)
                        }
                        Catch {
                            "ERROR: $($_.Exception.Message)"
                        }
                    }
                } |
Export-Csv -NoTypeInformation -Path C:\UserProfilesNotExist-Size.csv

正则表达式详细信息

^ 在字符串的开头断言位置
( 匹配下面的正则表达式并将其匹配捕获到反向引用编号 1
   \w 匹配作为“单词字符”的单个字符(字母、数字等)
      + 一次到无限次,尽可能多次,按需回馈(贪婪)
   \。匹配字符“.” 字面上地
   \w 匹配作为“单词字符”的单个字符(字母、数字等)
      + 一次到无限次,尽可能多次,按需回馈(贪婪)
)               
. 匹配任何不是换行符的单个字符
   * 在零次和无限次之间,尽可能多次,按需回馈(贪婪)

推荐阅读