Мы находимся в процессе миграции двух файловых серверов на новый сервер. Мы подключили диски через группу пользователей в групповой политике. Многие пользователи вручную сопоставили диски, и нам нужно найти эти сопоставления. Я создал сценарий 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