1

更新:在底部添加了另一个事实。


我疯了,试图理解为什么这个简单/明显/必要的功能不起作用(对我来说)。我找不到任何有同样问题的人,所以就像我改变了一些系统默认值(坏习惯)并搞砸了自己,现在发现自己处于“只是甜点”的接收端,但仍然.. .

问题陈述:

给定已找到且可执行的工作 powershell 脚本......为什么在将这些脚本移至 psdrive通过 $env:path 隐式调用(包括引用 psdrive 的脚本文件夹)时找不到这些脚本?(为清楚起见,此段已编辑)

测试用例:

1)通过运行创建本地磁盘psdrive:

new-psdrive -name home -psprovider filesystem -root $HOME

2)复制一个(工作的)豪华脚本(称之为“script.ps1”)到$HOME

3) $env:path += ";home:"

4) 将目录更改为 $HOME 以外的任何位置。

5)从打开的豪华命令窗口运行:“script”或“script.ps1”

我认为脚本应该通过引用 $env:path 中的“home:/”组件来找到。

找不到脚本。

只是为了咧嘴笑(并消除问题的内容),让 $HOME/script.ps1 的内容成为字符串:

"hello world"

当我跑

home:/script

或者

&"$HOME/script"

或(从 $HOME/Documents 调用)

../script

脚本打印...

hello world

Quelle惊喜,嗯?但是当我跑步时

script

或者

script.ps1

我收到熟悉的错误消息:

The term 'script' is not recognized as the name of a cmdlet, ...

然而家:在路上:

$ $env:path -split ";"
%SystemRoot%\system32\WindowsPowerShell\v1.0\
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
C:\Windows\System32\WindowsPowerShell\v1.0\
c:\Program Files\Sysinternals
C:\Program Files\Vim\vim73\
C:{my home directory}/psbin
home:/

如果我将 script.ps1 移动到 $HOME/psbin(也在 $env:path 中,但是一个普通文件夹,而不是 psdrive)并再次运行脚本,我得到:

$ script
hello world

总结:

时找不到豪华脚本

1) 脚本位于 psdrive 文件夹中

2) psdrive 文件夹位于 $env:path

3) 相对于 $env:path 中的 psdrive 文件夹组件(隐式)调用脚本,而不是使用绝对或相对路径。

请注意,在上面的测试用例中,脚本位于 C: 驱动器本地根的 psdrive 上。

进一步注意,“finding”/“notfinding”不是脚本本身的功能;它是脚本位置(特别是:psdrive / 不是 psdrive)以及调用是否依赖于 $env:path 的函数。

进一步注意,如果我使用绝对或相对于当前目录的路径调用它,脚本就会运行(再次表明这不是 acl/attr/gpo 问题。)

为什么从 $env:path 找不到脚本???

背景资料:

1) 我在作为 VMware Workstation 8.0.6 来宾、Win7HomePremium 同上运行的 Win7Pro 和裸机 WHS2011 服务器(通过 rdp 连接)中看到了这种行为;

2) 我在 32b Win7Pro (VM)、64b Win7HomePremium (VM) 和 64b WHS2011 (rdp) 上看到了这种行为;

3)当前用户和机器的执行策略设置为“绕过”(在其他范围内未定义)。

4)powershell 2.0版

5) pathext 由 .ps1 扩充:

$ $env:pathext
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.ps1

6)Win7/WHS2011系统全面打补丁


我究竟做错了什么?

FWIW,我使用 psdrives 因为我有长的路径(带有嵌入式空格......谢谢,VMware!)到主机上的文件。我不使用符号链接,因为 posh 带有符号链接复活节彩蛋:

https://connect.microsoft.com/PowerShell/feedback/details/727149/powershell-rm-rec-traverses-symbolic-links-and-removes-items-in-target

H T:

http://blog.rlucas.net/rants/dont-bother-with-symlinks-in-windows-7/

如果任何 posh+symlink 用户阅读此内容,则 rm -rf symlink-to-$HOME-folder 删除理论上没有问题:我以这种方式删除了我的大部分 linux 主目录(通过指向 VMware 主机共享的符号链接)文件夹,如果这一点不清楚。)

更新:

如果我将长路径(在我感兴趣的情况下,convert-path 返回的 UNC 路径)添加到 $env:path 而不是 psdrive-relative 路径,那么 posh 会找到脚本。

其中(再次)说问题不是网络驱动器的 acl/gpo/attr 问题(这是我的脚本所在的位置)。

在代码中,如果我将 $env:path 变量设置为:

$env:path += ";//vmware-host/Shared Folders/blah/psbin"

而不是

$env:path += ";blah:/psbin"

其中 blah: 是植根于 //vmware-host/Shared Folders/blah 的 psdrive。

不是激进或任何事情,但似乎 powershell 无法解析 $env:path 变量中的 psdrives。

谁能解释为什么会这样?我认为语言应该关闭它们自己的语义。

还是我忽略了一些基本/明显的观点?

4

1 回答 1

0

Get-Item、New-Item、Get-ChildItem 等都在 Microsoft.Powershell.Management 模块中。

在 Powershell 3 中,实际上可以在没有管理模块的情况下启动 powershell,因此也可以没有 *-Item 命令。

Get-Command、Invoke-Command 都在 Microsoft.Powershell.Core 模块中。

现在有趣的部分。

Remove-PSDrive -Name Home -EA SilentlyContinue
[void](New-PSDrive -Name Home -PSProvider Filesystem -Root $HOME)
Push-Location home: ; Set-Location \;
Push-Location C: ; cd $Home 

get-item home:, c: | Select -Property PSDrive, Root, FullName, PSPath | ft -autosize

PSDrive Root FullName             PSPath                                                    
------- ---- --------             ------                                                    
Home    C:\  C:\Users\DireKitten\ Microsoft.PowerShell.Core\FileSystem::C:\Users\DireKitten\
C       C:\  C:\Users\DireKitten  Microsoft.PowerShell.Core\FileSystem::C:\Users\DireKitten 

哦,看,完全一样。

TLDR:提供程序仅适用于 *-Item cmdlet,其他一切都需要本机 Windows UNC 路径。

于 2013-07-13T08:02:01.340 回答