Загрузка данных


$ErrorActionPreference = 'SilentlyContinue'

$Results = @()

# klipa1 ... klipa35
$KlipaPattern = '^klipa(?:[1-9]|[12][0-9]|3[0-5])$'

$UserProfiles = Get-ChildItem 'C:\Users' -Directory -Force |
    Where-Object {
        $_.Name -notin @(
            'Public',
            'Default',
            'Default User',
            'All Users'
        )
    }

$WshShell = New-Object -ComObject WScript.Shell

foreach ($UserProfile in $UserProfiles) {

    $UserName = $UserProfile.Name

    # Папки первого уровня профиля, кроме AppData
    $FirstLevelFolders = Get-ChildItem `
        -LiteralPath $UserProfile.FullName `
        -Directory `
        -Force `
        -ErrorAction SilentlyContinue |
        Where-Object {
            $_.Name -ne 'AppData'
        }

    foreach ($Folder in $FirstLevelFolders) {

        # ============================================================
        # RDP
        # ============================================================
        $RdpFiles = Get-ChildItem `
            -LiteralPath $Folder.FullName `
            -Recurse `
            -Force `
            -ErrorAction SilentlyContinue |
            Where-Object {
                -not $_.PSIsContainer -and
                $_.Extension -ieq '.rdp'
            }

        foreach ($RdpFile in $RdpFiles) {

            $FullAddressLine = Get-Content `
                -LiteralPath $RdpFile.FullName `
                -ErrorAction SilentlyContinue |
                Where-Object {
                    $_ -match '^\s*full\s+address\s*:'
                } |
                Select-Object -First 1

            if (-not $FullAddressLine) {
                continue
            }

            if ($FullAddressLine -match '^\s*full\s+address\s*:\s*s\s*:\s*(.+?)\s*$') {

                $Address = $Matches[1].Trim()

                # Убираем порт, например klipa1:3389
                $TargetHost = ($Address -split ':')[0].Trim()

                # Убираем доменную часть, например klipa1.domain.local
                $ShortHost = ($TargetHost -split '\.')[0].Trim()

                if ($ShortHost -match $KlipaPattern) {

                    $Results += [PSCustomObject]@{
                        User = $UserName
                        Host = $ShortHost
                        Type = 'RDP'
                        Path = $RdpFile.FullName
                    }
                }
            }
        }

        # ============================================================
        # LNK
        # ============================================================
        $LnkFiles = Get-ChildItem `
            -LiteralPath $Folder.FullName `
            -Recurse `
            -Force `
            -ErrorAction SilentlyContinue |
            Where-Object {
                -not $_.PSIsContainer -and
                $_.Extension -ieq '.lnk'
            }

        foreach ($LnkFile in $LnkFiles) {

            try {

                $Shortcut = $WshShell.CreateShortcut($LnkFile.FullName)

                $TargetPath = $Shortcut.TargetPath
                $Arguments  = $Shortcut.Arguments

                $MatchedHost = $null

                # ----------------------------------------------------
                # mstsc.exe /v:klipa1
                # mstsc.exe /v klipa1
                # mstsc.exe /v:klipa1:3389
                # ----------------------------------------------------
                if (
                    [System.IO.Path]::GetFileName($TargetPath) -ieq 'mstsc.exe'
                ) {

                    if (
                        $Arguments -match '(?i)/v(?::|\s+)\s*(klipa(?:[1-9]|[12][0-9]|3[0-5]))(?:[\.:]\S*)?'
                    ) {
                        $MatchedHost = $Matches[1]
                    }
                }

                # ----------------------------------------------------
                # Ярлык указывает непосредственно на RDP-файл
                # ----------------------------------------------------
                if (
                    -not $MatchedHost -and
                    $TargetPath -and
                    $TargetPath -match '\.rdp$' -and
                    (Test-Path -LiteralPath $TargetPath)
                ) {

                    $RdpLine = Get-Content `
                        -LiteralPath $TargetPath `
                        -ErrorAction SilentlyContinue |
                        Where-Object {
                            $_ -match '^\s*full\s+address\s*:'
                        } |
                        Select-Object -First 1

                    if (
                        $RdpLine -match '^\s*full\s+address\s*:\s*s\s*:\s*(.+?)\s*$'
                    ) {

                        $Address = $Matches[1].Trim()

                        $TargetHost = ($Address -split ':')[0].Trim()
                        $ShortHost = ($TargetHost -split '\.')[0].Trim()

                        if ($ShortHost -match $KlipaPattern) {
                            $MatchedHost = $ShortHost
                        }
                    }
                }

                if ($MatchedHost) {

                    $Results += [PSCustomObject]@{
                        User = $UserName
                        Host = $MatchedHost
                        Type = 'LNK'
                        Path = $LnkFile.FullName
                    }
                }
            }
            catch {
                # Битые или недоступные ярлыки пропускаем
            }
        }
    }
}

# Убираем дубли
$Results = $Results |
    Sort-Object User, Host, Type, Path -Unique

Write-Output '============================================================'
Write-Output 'RDP KLIPA SCAN'
Write-Output "Computer: $env:COMPUTERNAME"
Write-Output '============================================================'

if (-not $Results -or $Results.Count -eq 0) {

    Write-Output 'Совпадений не найдено.'

}
else {

    Write-Output "Найдено совпадений: $($Results.Count)"
    Write-Output ''

    foreach ($Result in $Results) {

        Write-Output "Пользователь : $($Result.User)"
        Write-Output "Клипа        : $($Result.Host)"
        Write-Output "Тип          : $($Result.Type)"
        Write-Output "Файл         : $($Result.Path)"
        Write-Output '------------------------------------------------------------'
    }
}

Write-Output 'Сканирование завершено.'