尽管$ env:path entry,但在psdrive上找不到Powershell脚本

时间:2013-07-11 01:51:43

标签: powershell path execution

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


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

问题陈述:

鉴于找到并可执行的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)从打开的posh命令窗口运行:“script”或“script.ps1”

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

找不到脚本。

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

"hello world"

当我跑步时

home:/script

&"$HOME/script"

或(从$ HOME / Documents调用)

../script

脚本打印...

hello world
Quel很惊讶,嗯?但是当我跑步时

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上。

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

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

为什么不从$ env:path ???

找到脚本

背景资料:

1)我在Win7Pro中看到这种行为,作为VMware Workstation 8.0.6来宾,Win7HomePremium同上,以及裸机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!)到主机上的文件。我没有使用符号链接,因为豪华带有符号链接复活节彩蛋:

  

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 +符号链接用户读取此内容,rm -rf符号链接到$ HOME文件夹删除不是理论上的问题:我通过符号链接删除了我的linux主目录的大部分内容(通过符号链接到VMware主机共享文件夹,如果不清楚的话。)

更新

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

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

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

,powershell将解析我的脚本的路径
$env:path += ";//vmware-host/Shared Folders/blah/psbin"

而不是

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

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

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

任何人都可以解释为什么会这样吗?我认为应该用他们自己的语义来关闭语言。

或者我忽略了一些基本/明显的观点?

1 个答案:

答案 0 :(得分: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路径。