两种不同版本的Powershell 5.1中的获取子项以不同的方式处理很长的路径

时间:2019-01-09 23:26:27

标签: powershell

尝试维护使用Powershell Get-ChildItem扫描Windows目录并列出其内容的例程。

由于Powershell代表了Windows附带的下一代控制台,因此您会认为遍历文件系统(最基本的计算机功能)会遇到麻烦,但是会带来一些麻烦。

符号链接循环逐项列出是一个问题(通过排除-Attribute!ReparsePoints解决)

另一个令人讨厌的问题是文件路径过长。无论出于什么原因,当路径超过某个字符长度时,某些Powershell配置都无法列出文件。

探索的解决方法:

  • 使用-LiteralPath代替-Path,并在路径中放置\\?\\\?\UNC\前缀 Handling Path Too Long Exception with New-PSDrive

  • 将更长路径的一部分映射到带字母的PS驱动器以在字符数限制内进入(带字母的驱动器“替代方法”允许执行get-childItem命令,但产生相同的“路径太长”错误。

  • 安装Powershell 6(CORE)希望以某种方式固化Powershell 5.1

令我惊讶的是,我在桌面上测试了该例程,它的长路径没有问题,根本不需要任何特殊处理。 (最长路径为300个字符)

但是,当我在Windows Server 2012(虚拟机)上运行相同命令时,它仍然步履蹒跚。

两台机器现在都在运行Powershell 5.1,这是$ PSVersionTable

DESKTOP Win7 INSTANCE(工作正常)

Name                           Value
----                           ----
PSVersion                      5.1.14409.1018
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0,4.0...}
BuildVersion                   10.0.14409.1018
CLRVersion                     4.0.30319.42000

SERVER 2012实例(无法处理长路径)

Name                           Value
----                           -----
PSVersion                      5.1.14409.1005
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14409.1005
CLRVersion                     4.0.30319.36460

有什么想法可以使SERVER 2012 INSTANCE正常运行吗?我发现Powershell 5.1的内部版本号不同,不确定如何将内部版本一致,您认为这是根本原因吗?

2012 Server正在做的另一件奇怪的事情是,默认情况下,Powershell不会从Windows资源管理器中获取映射的网络驱动器。因此,如果我将驱动器“ X:”映射到其他网络位置,则默认情况下,2012 Server无法在Powershell中看到它,并且需要手动安装PS驱动器才能“复制” Windows已经使用的映射驱动器。资源管理器。

感谢您的帮助,只是试图跟踪某些文件! :D

2 个答案:

答案 0 :(得分:0)

Windows 10是否可以运行取决于您可以启用的本地组策略,这称为启用Win32长路径

要设置此策略,您需要预先安装:

  • Windows Management Framework 5.1(如果安装了Powershell 5.1,您将拥有它)
  • .net Framework 4.6.2或更高版本。
  • 至少Windows Server 2016(1607)/ Windows 10

可以通过以下方式启用该策略:

#GPEdit location:  Configuration>Administrative Templates>System>FileSystem 
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1

要查询

$LongPathEnabled = (Get-ItemPropertyValue 'HKLM:\System\CurrentControlSet\Control\FileSystem\' -Name 'LongPathsEnabled') -eq 1
Write-host "LongPath policy configuration state: $LongPathEnabled"

如果启用它,则无需指定引用的第一个链接中非常聪明的答案所描述的文字路径符号,就可以使用长路径。

但是,根据我发现的文档,此策略在Windows Server 2012上将不可用。 我相信要支持这种“旧式”基础结构,您需要使用LiteralPath并指定Unicode表示法(\?\ UNC \和'\?\ c:\)

注意事项

即使以RTM 1607和更高接收系统为目标,也无法保证将启用该策略。如果您在无法按照自己的意愿更新本地策略的系统上工作,那么最好使用LiteralPath和unicode表示法。启用长路径策略只是在周年更新中刚刚引入的。

参考

Long Path Support In Powershell

Microsoft - Download Group Policy Settings Reference for Windows and Windows Server

Myself

答案 1 :(得分:0)

非常感谢您的指导,我当然希望进一步探索通过本地组策略执行的“启用Win32长路径”

但是,看起来我能够通过.NET更新在Windows Server 2012上运行它。

在先前研究的线程中,一个响应者提到了.NET CLR版本: PathTooLong error with Get-ChildItem in PowerShell v3, but not v2

“ Powershell v2和v3之间的一个重要区别是它运行在.NET CLR的版本上。Powershellv2使用.NET 2.0 CLR运行(不要与.NET Framework v2混淆。 0),而Powershell v3使用.NET 4.0 CLR运行(再次,不要与.NET Framework 4.0混淆。)4.0 CLR对于例外情况的宽容程度较低。– Matthew Brubaker,11月9日。

$ PSVersionTable返回CLRVersion的条目,并且我的台式机和服务器未对齐。我检查了.NET Framework版本,并且桌面使用的是.NET 4.7.1,而服务器的版本是.NET 4.5。

我已经在服务器上安装了.NET 4.7.1,但它似乎并不健康,因此已将其卸载并重新安装,但这没有用。然后我去了Microsoft,并获得了.NET 4.7.2的新安装程序。

一旦安装了.NET 4.7.2,服务器上的$ PSVersionTable将与工作桌面对齐,并且get-childitem能够解析很长的路径而不会出现问题。

名称值
---- -----
PSVersion 5.1.14409.1005
PSEdition桌面
PSCompatibleVersions {1.0、2.0、3.0、4.0 ...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1