如何过滤 Powershell 以将目录名称与 AD SamAccountName 进行比较并忽略 .Vx 模式?

How to filter Powershell to compare directory name against AD SamAccountName and ignoring the .Vx pattern?

我的 AD 用户帐户的格式类似于 First.Last 名称 (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 名称 (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 数据库进行比较,以分离孤立的主目录。

您可以在目录名称上使用正则表达式 -replace 以仅获取 Firstname.Lastname 部分,跳过 .Vx.RENAME(或 .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+).*', '') } },
              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 User Exist' 列,因为您知道这些是孤立的用户文件夹。

Get-ChildItem -Path $ServerHomeDirShare -Directory | 
Where-Object { $users -notcontains ($_.Name -replace '^(\w+\.\w+).*', '') } |
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

正则表达式详细信息

^                Assert position at the beginning of the string
(                Match the regular expression below and capture its match into backreference number 1
   \w            Match a single character that is a “word character” (letters, digits, etc.)
      +          Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   \.            Match the character “.” literally
   \w            Match a single character that is a “word character” (letters, digits, etc.)
      +          Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)               
.                Match any single character that is not a line break character
   *             Between zero and unlimited times, as many times as possible, giving back as needed (greedy)