我们正在将两个文件服务器迁移到新服务器。我们已通过组策略中的用户组映射驱动器。许多用户已手动映射驱动器,我们需要找到这些映射。我创建了一个 PowerShell 脚本来远程运行以获取驱动器映射。它可以在大多数计算机上运行,但有许多计算机没有返回结果,而且我没有收到任何错误消息。列表上的每个工作站都会创建一个文本文件,而那些没有返回结果的工作站在文件中没有文本。我可以 ping 这些机器。如果机器没有打开,就会出现错误消息,提示 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
答案1
从一些快速测试来看,它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
}
}
}
答案2
我们在登录时使用下面的脚本。在组策略中指定。
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