Назад | Перейти на главную страницу

скрипт для вывода списка подключенных пользователем дисков, не выдающих результатов или ошибок

Мы находимся в процессе миграции двух файловых серверов на новый сервер. Мы подключили диски через группу пользователей в групповой политике. Многие пользователи вручную сопоставили диски, и нам нужно найти эти сопоставления. Я создал сценарий PowerShell для запуска удаленного получения сопоставлений дисков. Он работает на большинстве компьютеров, но многие из них не возвращают результаты, и я не получаю сообщений об ошибках. Каждая рабочая станция в списке создает текстовый файл, а те, которые не возвращают результаты, не имеют текста в файлах. Я могу пинговать эти машины. Если машина не включена, появляется сообщение об ошибке, что сервер RPC недоступен. Моя учетная запись пользователя домена находится в группе, которая находится в локальной учетной записи администратора. Понятия не имею, почему некоторые не работают.

Вот сценарий.

# Load list into variable, which will become an array of strings

If( !(Test-Path C:\Scripts)) { New-Item C:\Scripts -ItemType directory }
If( !(Test-Path C:\Scripts\Computers)) { New-Item C:\Scripts\Computers -ItemType directory }
If( !(Test-Path C:\Scripts\Workstations.txt)) { "No Workstations found. Please enter a list of Workstations under Workstation.txt"; Return}
If( !(Test-Path C:\Scripts\KnownMaps.txt)) { "No Mapping to check against. Please enter a list of Known Mappings under KnownMaps.txt"; Return}

$computerlist = Get-Content C:\Scripts\Workstations.txt

# Loop through each item in the array (each computer in the list of computers we loaded into the variable)
ForEach ($computer in $computerlist)
{

   $diskObject =  Get-WmiObject Win32_MappedLogicalDisk -computerName $computer | Select Name,ProviderName | Out-File C:\Tester\Computers\$computer.txt -width 200

}

Select-String -Path C:\Tester\Computers\*.txt -Pattern cmsfiles | Out-File C:\Tester\Drivemaps-all.txt

$strings = Get-Content C:\Tester\KnownMaps.txt

Select-String -Path C:\Tester\Drivemaps-all.txt -Pattern $strings -notmatch -simplematch | Out-File C:\Tester\Drivemaps-nonmatch.txt -Width 200
Select-String -Path C:\Tester\Drivemaps-all.txt -Pattern $strings -simplematch | Out-File C:\Tester\Drivemaps-match.txt -Width 200

Некоторые быстрые тесты показывают, что Get-WmiObject Win32_MappedLogicalDisk -computerName $computer имеет некоторые ограничения. Из того, что я читаю, можно определить, есть ли у текущего пользователя права администратора на своем компьютере, возвращает ли это что-нибудь или нет.

Другой вариант - пройти через реестр. Эта команда перечисляет подключенные диски для текущего пользователя, но вам придется использовать Invoke-Command чтобы выполнить его удаленно.

Invoke-Command -ComputerName $computer -ScriptBlock {Get-ChildItem HKCU:Network}

Если вам нужно получить сопоставления дисков, используемые всеми пользователями, в моем тестировании это работает:

# Connect to registry on remote computer and pull a list of user keys
$computer="remotecomputer"
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', $computer)
$UserKeys = $Reg.GetSubKeyNames()

# Loop through the user keys and access the Network subkey, which contains the user's drive mappings
for ($i=0; $i -lt $Reg.SubKeyCount; $i++) {
    $NetKey = $Reg.OpenSubKey("$($UserKeys[$i])\\Network")

# If the user has any mapped drives, get the subkeys containing those drives
    if ($NetKey.SubKeyCount -gt 0) {
        $DriveKeys = $NetKey.GetSubKeyNames()
        for ($n=0; $n -lt $DriveKeys.Length; $n++) {
            $DriveKey = $Reg.OpenSubKey("$($UserKeys[$i])\\Network\\$($DriveKeys[$n])")

# Output the drive letter and the network path
        "Drive Letter: " + $DriveKeys[$n]
        "Network Path: " + $DriveKey.GetValue("RemotePath")

# Close each of the loops and conditions
        }
    }
}

Мы используем этот сценарий ниже при входе в систему. Указывается в групповой политике.

Option Explicit

Dim objFSO, objLogFile, objNetwork, objShell, strText, intAns
Dim intConstants, intTimeout, strTitle, intCount, blnLog
Dim strUserName, strComputerName, strShare, strLogFile
Dim objDrives, strDrive, strPath, k, strMessage
Dim objPrinters, strPrinter, strPrinterPath

strShare = "\\BCSRV007\Shared"
strLogFile = "Domain.log"
intTimeout = 20

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objNetwork = CreateObject("Wscript.Network")
Set objShell = CreateObject("Wscript.Shell")

strUserName = objNetwork.UserName
strComputerName = objNetwork.ComputerName

strMessage = "Logon at: " & CStr(Now()) _
    & vbCrLf & "  User: " & strUserName _
    & vbCrLf & "  Computer: " & strComputerName

' Enumerate mapped drives.
Set objDrives = objNetwork.EnumNetworkDrives
For k = 0 To objDrives.Count - 2 Step 2
    strDrive = objDrives(k)
    strPath = objDrives(k + 1)
    If (strDrive = "") Then
        strDrive  = "--"
    End If
    strMessage = strMessage _
        & vbCrLf & "  Drive " & strDrive & " mapped to " & strPath
Next

' Enumerate printers.
Set objPrinters = objNetwork.EnumPrinterConnections
For k = 0 To objPrinters.Count - 2 Step 2
    strPrinter = objPrinters(k)
    strPrinterPath = objPrinters(k + 1)
    If (strPrinter = "") Then
        strPrinter = "--"
    End If
    strMessage = strMessage _
        & vbCrLf & "  Printer " & strPrinter & " mapped to " & strPrinterPath
Next

' Log date/time, user name, computer name, mapped drives, and
' mapped printers.
If (objFSO.FolderExists(strShare) = True) Then
    On Error Resume Next
    Set objLogFile = objFSO.OpenTextFile(strShare & "\" _
        & strLogFile, 8, True, 0)
    If (Err.Number = 0) Then
        ' Make three attempts to write to log file.
        intCount = 1
        blnLog = False
        Do Until intCount = 3
            objLogFile.WriteLine strMessage
            If (Err.Number = 0) Then
                intCount = 3
                blnLog = True
            Else
                Err.Clear
                intCount = intCount + 1
                If (Wscript.Version > 5) Then
                    Wscript.Sleep 200
                End If
            End If
        Loop
        On Error GoTo 0
        If (blnLog = False) Then
            strTitle = "Logon Error"
            strText = "Log cannot be written."
            strText = strText & vbCrlf _
                & "Another process may have log file open."
            intConstants = vbOKOnly + vbExclamation
            intAns = objShell.Popup(strText, intTimeout, strTitle, _
                intConstants)
        End If
        objLogFile.Close
    Else
        On Error GoTo 0
        strTitle = "Logon Error"
        strText = "Log cannot be written."
        strText = strText & vbCrLf & "User may not have permissions,"
        strText = strText & vbCrLf & "or log folder may not be shared."
        intConstants = vbOKOnly + vbExclamation
        intAns = objShell.Popup(strText, intTimeout, strTitle, intConstants)
    End If
    Set objLogFile = Nothing
End If