Update: added another factoid at the bottom.
I am going nuts trying to understand why this simple / obvious / necessary functionality doesn't work (for me). I haven't been able to find anyone with the same problem, so like as not I've changed some system default (bad habit) and screwed myself and now find myself on the receiving end of "just desserts", but still ...
Problem statement:
Given working powershell scripts which are found and executable ... why aren't these scripts found when they're moved to a psdrive and are implicitly invoked via $env:path (which includes the script folder referenced to the psdrive)? (this para edited for clarity)
Test case:
1) Create a local disk psdrive by running:
new-psdrive -name home -psprovider filesystem -root $HOME
2) copy a (working) posh script (call it "script.ps1") to $HOME
3) $env:path += ";home:"
4) change directory to any place but $HOME.
5) from an open posh command window run: "script" or "script.ps1"
I submit that the script should be found by reference to the "home:/" component in $env:path.
The script isn't found.
Just for grins (and to eliminate content as the problem), let the contents of $HOME/script.ps1 be the string:
"hello world"
When I run
home:/script
or
&"$HOME/script"
or (invoking from $HOME/Documents)
../script
the script prints ...
hello world
Quelle surprise, eh? But when I run
script
or
script.ps1
I get the familiar error message:
The term 'script' is not recognized as the name of a cmdlet, ...
Yet home: is in the path:
$ $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:/
if I move script.ps1 to $HOME/psbin (also in $env:path, but a regular folder, not a psdrive) and run the script again, I get:
$ script
hello world
Summarizing:
posh scripts are not found when
1) the script is in a psdrive folder
2) the psdrive folder is in $env:path
3) the script is invoked (implicitly) relative to the psdrive folder component in $env:path rather than with an absolute or relative path.
Note that in the test case above the script is on a psdrive rooted locally on the C: drive.
Note further that "finding"/"not finding" is not a function of the script itself; it's a function of the location of the script (specifically: psdrive / not psdrive) and whether the invocation relies on $env:path.
Note further that the script runs if I invoke it with an absolute or relative-to-current-directory path (suggesting again that this isn't an acl/attr/gpo problem.)
Why isn't the script found from $env:path???
Background information:
1) I see this behavior in Win7Pro running as a VMware Workstation 8.0.6 guest, Win7HomePremium ditto, and in a bare-metal WHS2011 server (connecting via rdp);
2) I see this behavior on 32b Win7Pro (VM), 64b Win7HomePremium (VM) and 64b WHS2011 (rdp);
3) Execution Policy is set to "bypass" for Current User & Machine (and is undefined in other scopes).
4) powershell version 2.0
5) pathext is augmented by .ps1:
$ $env:pathext
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.ps1
6) Win7 / WHS2011 systems fully patched
What am I doing wrong?
FWIW, I use psdrives because I have very long paths (with embedded spaces ... thanks, VMware!) to files on the host machine. I don't use symlinks because posh comes with a symlink Easter egg:
h/t:
http://blog.rlucas.net/rants/dont-bother-with-symlinks-in-windows-7/
Should any posh+symlink user read this, rm -rf symlink-to-$HOME-folder deletion is no theoretical concern: I came within a keystroke of deleting a large fraction of my linux home directory this way (via symlinks to VMware host shared folders, should the point be unclear.)
Update:
If I add the long path (in the case of interest to me, the UNC path that convert-path returns) to $env:path rather than the psdrive-relative path, then posh finds the script.
Which (again) says that the problem isn't an acl/gpo/attr problem with a network drive (which is where my script is).
In code, powershell resolves the path to my script if I set my $env:path variable with:
$env:path += ";//vmware-host/Shared Folders/blah/psbin"
rather than
$env:path += ";blah:/psbin"
where blah: is the psdrive rooted at //vmware-host/Shared Folders/blah.
Not to be radical or anything, but it appears that powershell can't resolve psdrives in the $env:path variable.
Can anyone explain why this should be so? I thought that languages should be closed wrt their own semantics.
Or am I overlooking some fundamental / obvious point?