在 UNC 路径 \\SERVERNAME 的根目录下使用 Get-Childitem
Using Get-Childitem at root of UNC Path \\SERVERNAME
我们正在尝试使用 PowerShell 作为文件复制工具,但遇到了问题。
源服务器是基于 Linux 的封闭式 OS,用户可在其中通过 GUI 创建多个网络共享,然后可通过 UNC 路径 \SERVERNAME\NETWORKSHARE
访问。当然,在OS中,NETWORKSHARE实际上位于比root更深的多个级别。
我们已经与 OS 的开发人员进行了交谈,他们 cannot/will 不允许访问存储所有 NETWORKSHARE 文件夹的根目录。
我已经求助于 PowerShell 来尝试找到一种方法。我最初的想法是将 Get-ChildItem -Directory
发送到 \SERVERNAME
以获取所有 NETWORKSHARES,然后将其通过管道发送到 Copy-Item/Robocopy
,但它不起作用。
我知道服务器需要自己的本地(非 AD)凭据。
有没有办法做我想做但我没有看到的事情?
提前致谢!
带有 IP 的 net view
命令将枚举可访问的 SMB/Samba 共享。
此 PowerShell 脚本解析输出和 returns 具有服务器和共享属性的 [PSCustomObject]
。
## Enum-SambaShares.ps1
$ServerList = ('192.168.133.67','192.168.133.46','192.168.133.76','192.168.133.28')
$ServerShares = ForEach ($Server in $ServerList) {
net view "\$Server" 2>$Null | Select-String '^([^ ]+)\s+(Disk|Platte)' |
ForEach-Object {
[PSCustomObject]@{
Server = $Server
Share = $_.matches.groups[1].Value
}
}
}
$ServerShares
示例输出:
Server Share
------ -----
192.168.133.67 Backup
192.168.133.67 Daten
192.168.133.67 Video-Unc
192.168.133.46 SambaShare
192.168.133.46 UserName
192.168.133.76 C
192.168.133.28 McDaten
192.168.133.28 Music
192.168.133.28 UserName
解析 new view
的输出有点笨拙。这是一种直接从 PowerShell 调用 NetShareEnum
Win32 API 并将结果作为对象输出的方法:
# Get-NetShare.ps1
#requires -version 2
param(
[String] $ComputerName = "."
)
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)]
public string shi1_netname;
public uint shi1_type;
[MarshalAs(UnmanagedType.LPWStr)]
public string shi1_remark;
}
public static class NetApi32
{
[DllImport("netapi32.dll", SetLastError = true)]
public static extern int NetApiBufferFree(IntPtr Buffer);
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int NetShareEnum(
StringBuilder servername,
int level,
ref IntPtr bufptr,
uint prefmaxlen,
ref int entriesread,
ref int totalentries,
ref int resume_handle);
}
"@
$pBuffer = [IntPtr]::Zero
$entriesRead = $totalEntries = $resumeHandle = 0
$result = [NetApi32]::NetShareEnum(
$ComputerName, # servername
1, # level
[Ref] $pBuffer, # bufptr
[UInt32]::MaxValue, # prefmaxlen
[Ref] $entriesRead, # entriesread
[Ref] $totalEntries, # totalentries
[Ref] $resumeHandle # resumehandle
)
if ( ($result -eq 0) -and ($pBuffer -ne [IntPtr]::Zero) -and ($entriesRead -eq $totalEntries) ) {
$offset = $pBuffer.ToInt64()
for ( $i = 0; $i -lt $totalEntries; $i++ ) {
$pEntry = New-Object IntPtr($offset)
$shareInfo = [Runtime.InteropServices.Marshal]::PtrToStructure($pEntry, [Type] [SHARE_INFO_1])
$shareInfo
$offset += [Runtime.InteropServices.Marshal]::SizeOf($shareInfo)
}
[Void] [NetApi32]::NetApiBufferFree($pBuffer)
}
if ( $result -ne 0 ) {
Write-Error -Exception (New-Object ComponentModel.Win32Exception($result))
}
您可以获得远程计算机的磁盘共享:
Get-NetShare sambaservername | Where-Object { $_.shi1_type -eq 0 }
我们正在尝试使用 PowerShell 作为文件复制工具,但遇到了问题。
源服务器是基于 Linux 的封闭式 OS,用户可在其中通过 GUI 创建多个网络共享,然后可通过 UNC 路径 \SERVERNAME\NETWORKSHARE
访问。当然,在OS中,NETWORKSHARE实际上位于比root更深的多个级别。
我们已经与 OS 的开发人员进行了交谈,他们 cannot/will 不允许访问存储所有 NETWORKSHARE 文件夹的根目录。
我已经求助于 PowerShell 来尝试找到一种方法。我最初的想法是将 Get-ChildItem -Directory
发送到 \SERVERNAME
以获取所有 NETWORKSHARES,然后将其通过管道发送到 Copy-Item/Robocopy
,但它不起作用。
我知道服务器需要自己的本地(非 AD)凭据。
有没有办法做我想做但我没有看到的事情?
提前致谢!
带有 IP 的 net view
命令将枚举可访问的 SMB/Samba 共享。
此 PowerShell 脚本解析输出和 returns 具有服务器和共享属性的 [PSCustomObject]
。
## Enum-SambaShares.ps1
$ServerList = ('192.168.133.67','192.168.133.46','192.168.133.76','192.168.133.28')
$ServerShares = ForEach ($Server in $ServerList) {
net view "\$Server" 2>$Null | Select-String '^([^ ]+)\s+(Disk|Platte)' |
ForEach-Object {
[PSCustomObject]@{
Server = $Server
Share = $_.matches.groups[1].Value
}
}
}
$ServerShares
示例输出:
Server Share
------ -----
192.168.133.67 Backup
192.168.133.67 Daten
192.168.133.67 Video-Unc
192.168.133.46 SambaShare
192.168.133.46 UserName
192.168.133.76 C
192.168.133.28 McDaten
192.168.133.28 Music
192.168.133.28 UserName
解析 new view
的输出有点笨拙。这是一种直接从 PowerShell 调用 NetShareEnum
Win32 API 并将结果作为对象输出的方法:
# Get-NetShare.ps1
#requires -version 2
param(
[String] $ComputerName = "."
)
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)]
public string shi1_netname;
public uint shi1_type;
[MarshalAs(UnmanagedType.LPWStr)]
public string shi1_remark;
}
public static class NetApi32
{
[DllImport("netapi32.dll", SetLastError = true)]
public static extern int NetApiBufferFree(IntPtr Buffer);
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int NetShareEnum(
StringBuilder servername,
int level,
ref IntPtr bufptr,
uint prefmaxlen,
ref int entriesread,
ref int totalentries,
ref int resume_handle);
}
"@
$pBuffer = [IntPtr]::Zero
$entriesRead = $totalEntries = $resumeHandle = 0
$result = [NetApi32]::NetShareEnum(
$ComputerName, # servername
1, # level
[Ref] $pBuffer, # bufptr
[UInt32]::MaxValue, # prefmaxlen
[Ref] $entriesRead, # entriesread
[Ref] $totalEntries, # totalentries
[Ref] $resumeHandle # resumehandle
)
if ( ($result -eq 0) -and ($pBuffer -ne [IntPtr]::Zero) -and ($entriesRead -eq $totalEntries) ) {
$offset = $pBuffer.ToInt64()
for ( $i = 0; $i -lt $totalEntries; $i++ ) {
$pEntry = New-Object IntPtr($offset)
$shareInfo = [Runtime.InteropServices.Marshal]::PtrToStructure($pEntry, [Type] [SHARE_INFO_1])
$shareInfo
$offset += [Runtime.InteropServices.Marshal]::SizeOf($shareInfo)
}
[Void] [NetApi32]::NetApiBufferFree($pBuffer)
}
if ( $result -ne 0 ) {
Write-Error -Exception (New-Object ComponentModel.Win32Exception($result))
}
您可以获得远程计算机的磁盘共享:
Get-NetShare sambaservername | Where-Object { $_.shi1_type -eq 0 }