Powershell 5.0 doesn't see PATH environment variables under User account - powershell

I added an environment variable to my System Path -> C:\Program Files\TEE-CLC. After that, I expect, that I can run my foo.exe which is under C:\Program Files\TEE-CLC from PowerShell without providing a full path to it. The issue is when I start a new, fresh Powershell session under my user, it doesn't see the newly added path, but when I start it under administrator everything works fine.
I checked $env:Path in both modes (User and Admin) and found that my new path doesn't exist when I am under User, but I can see it when Powershell is as Administrator
How I can make my newly added variable visible running under User rather than Administrator?
UPDATE
I ran 2 commands under User and the result is different. Why doesn't $env:Path display the same output as [System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE') and why current PSSession doesn't see the path from the latter command?`
STEPS TO REPRODUCE
Add environemt path variable [Environment]::SetEnvironmentVariable('PATH', ($env:Path + ';C:\Program Files\Foo'), 'MACHINE')
Close the session
Open a NEW ps session as user -> check $env:PATH -> C:\Program Files\Foo is not there
Open a NEW ps session as admin -> check $env:PATH -> C:\Program Files\Foo is there

Unless I've missed something, I cannot reproduce your issue, here's example, I've just perfromed on a Test machine for you.
First I opened an elevated powershell.exe window, i.e. 'as administrator`:
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
PS C:\WINDOWS\system32> $Env:Path
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps
PS C:\WINDOWS\system32> [Environment]::SetEnvironmentVariable('Path', ($Env:Path + ';C:\Program Files\Foo'), 'MACHINE')
PS C:\WINDOWS\system32> $Env:Path
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps
PS C:\WINDOWS\system32> [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Foo
PS C:\WINDOWS\system32>
Then I opened a new non elevated powershell.exe window:
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
PS C:\Users\Tester> $Env:Path
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Foo;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps;
PS C:\Users\Tester> [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Foo
PS C:\Users\Tester>
As you can see C:\Program Files\Foo was shown in both example outputs.
Then I opened another new elevated powershell.exe window:
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
PS C:\WINDOWS\system32> $Env:Path
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Foo;
PS C:\WINDOWS\system32> [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\Tester\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Foo
PS C:\WINDOWS\system32>
As you can see C:\Program Files\Foo was shown in both example outputs.

This issue suddenly appeared for me out of the blue and I was able to solve it for myself at least.
Warning: backup your PATH somewhere before running anything. There's a 1024ch limit so be careful.
Background
As a user (non-admin), your $Path is the equivalent of [System.Environment]::GetEnvironmentVariable('PATH', 'USER') while as admin your $Path is the equivalent of [System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE'). There are probably many instances where you want these separated. In my case everything under my "MACHINE" $Path are things I'd want as a regular user, so I'll just show how to combine these paths so that no matter how you run powershell you'll have the same path.
Process
Open cmd.exe as an administrator (there's probably a way to do this in powershell but this method seems so much easier and will apply to powershell fine)
Add the combined paths to the user path:
setx path "%path%"
(within cmd %path% is a combination of both the user and machine paths)
(Extra) Add the combined paths to the system path:
setx /M path "%path%"
Restart powershell. The executables you expect should now be available as a user.

Related

Start new shell not working when the ps1 has become executable with ps2exe

I am trying to create an executable (.exe) at windows that will perform some actions at first, and then open an interactive shell. In my case the interactive shell I want to be a wsl, but the problem is shown with every type of shells created.
For example:
Supposing that we have the file
test.ps1
Write-Host "Hello from my test program"
Invoke-Expression "powershell"
If I run it with the command: ./test.ps1, the outcome will be to print the message and start a new powershell instance.
If i run the command: Invoke-ps2exe .\test.ps1 test.exe, and then run the test.exe, the outcome will be:
Hello from my test program
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
but I cannot write anything at the window.
Can anyone explain me why this is happening, and how I could overcome this?
Modify your test.ps1 file as follows:
Write-Host "Hello from my test program"
Start-Process -Wait -NoNewWindow powershell.exe
This change ensures that PowerShell's usual interactive host, ConsoleHost, in the newly launched PowerShell session launched from your script doesn't run on top of the simplified host that is built into the .exe files that ps2exe generates, which appears to cause your problems.

PSExec: cmd exited on [COMPUTER] with error code -196608

I've been working on trying to run a Powershell script on the network using PSExec, but every time I run it, I get this message:
PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
Couldn't access [COMPUTER]:
The filename, directory name, or volume label syntax is incorrect.
C:\PSTools> psexec \\[COMPUTER] /s cmd /c %SystemRoot%\system32\WindowsPowerShell\
v1.0\powershell.exe -ExecutionPolicy Bypass -file c:\apps\test.ps1
PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
The argument 'c:\apps\test.ps1' to the -File parameter does not exist. Provide
the path to an existing '.ps1' file as an argument to the -File parameter.
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
cmd exited on [COMPUTER] with error code -196608.
The goal of the script is to traverse domain-connected laptops and save a specific list of directories to a file on my computer. That script is as follows:
powershell.exe -command "& {& get-childitem 'c:\users\*\appdata\local\google\chrome\user*data\default\extensions\*'}" > \\[MY_COMPUTER]\C$\users\[USERNAME]\desktop\Chrome_Extensions.txt
I am calling this script with this command:
psexec \\[COMPUTER] /s cmd /c %SystemRoot%\system32\WindowsPowerShell\
v1.0\powershell.exe -ExecutionPolicy Bypass -file c:\apps\test.ps1
When I run the script without psexec \\[COMPUTER] /s , it runs fine and saves the correct information about the computer I'm running it on, then sends the information to my computer's desktop. But running it with the aforementioned line causes the error above, and I can't target machines on the network. So, what about the PSExec command causes this to error out, as it doesn't seem like there's really a lot to it? Perhaps I'm misunderstanding, and assuming that PSExec should run the same as PowerShell, which very well might not be the case. I guess I'm just a little lost on how to use it, and any assistance would be greatly appreciated! Thank you!
With help from #Briantist, I've been able to run the command Enable-PSRemoting on the target computer, then run the script with invoke-command -computername [COMPUTER] -filepath c:\apps\test.ps1
Using PSExec was just too messy, so I'm glad this was able to work another way. Now to figure out how to enable remoting on all computers on the domain without connecting to all of them individually and doing it manually...

How does one import module inside the cmd?

Currently, I'm using this,
cd Images powershell.exe & Import-Module .\Resize-Image.psm1 & Resize-Image ....
What this does in PS, is that it will import the module and I'm able to use it's function to rescale my pictures and output it, it works pretty well in PS but i'm intending to use cmd prompt to call this as my other lines of codes are in cmd prompt.
When i use this in cmd, it just displays
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
and is waiting for a new command even though the above code is in a .bat file.
The code presented starts PowerShell, but has no command for it. After the AMPERSAND, the next command is Import-Module which is unknown to cmd.exe.
PowerShell commands can be separated by a SEMICOLON character.
cd Images
powershell.exe -NoLogo -NoProfile -Command ^
"Import-Module .\Resize-Image.psm1; Resize-Image ...."
If you could run in PowerShell:
Set-Location './Images' # probably should have a fully-qualified path
Import-Module './Resize-image.psm1'
Resize-Image ...

Where to put PowerShell profile scripts if standard locations are forbidden?

In our corporate environment, I am having difficulty with creating a PowerShell profile scripts.
To prevent users from writing documents on the local disk, the "Documents" directory is forced to be on a network drive. Commonly the "H:" (home) drive.
Likewise, users are forbidden from writing under C:\Windows\System32.
Where can I put the ISE profile script if these two are not available?
PSVersion 5.0.10586.117
PS C:\Windows\System32\WindowsPowerShell\v1.0> $HOME, $PSHOME
C:\Users\pwatson
C:\Windows\System32\WindowsPowerShell\v1.0
See also: Help-About about_Profiles
When I am not connected to the network, these are the $profile settings. I still cannot write under C:\Windows\System32 and the CurrentUser values are invalid.
PS C:\Windows\System32\WindowsPowerShell\v1.0> $profile | Get-Member -Type NoteProperty | ForEach-Object {$_.ToString
()}
string AllUsersAllHosts=C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1
string AllUsersCurrentHost=C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
string CurrentUserAllHosts=WindowsPowerShell\profile.ps1
string CurrentUserCurrentHost=WindowsPowerShell\Microsoft.PowerShell_profile.ps1
PS C:\Windows\System32\WindowsPowerShell\v1.0>
One option is to create a shortcut with a target like this:
%systemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit -file C:\somewhere\myprofile.ps1
and then always use this shortcut to start PowerShell.
This is not actually using the built-in PowerShell profile concept but it is dot-sourcing a ps1 file that behaves pretty much like a profile file.
If you like to start PowerShell from cmd.exe, create a batch-file with the same content as above and put it somewhere in your path (if you have permissions to do so)

PowerShell (2.0, 32-bit) can't load TFS 2010 snap-in... except when it can

I have a PowerShell script which interacts with Team Foundation Server. When I run it in the PowerShell console, it works perfectly. This is nice for testing it, but I want to run it by double-clicking on it, or on a batch file or something. I'd even settle for right-clicking on it and selecting "Run with PowerShell".
But when I do that, I get an error. "Run with PowerShell" closes the window too fast to see what the error is. Somebody was really thinking when they designed that, maybe Ballmer was involved. I can also run it in cmd.exe, like so:
PowerShell -File dostufftocheckouts.ps1
When I do that, I get to see an error message, and I'm guessing it might be the same one:
Get-PSSnapin : No Windows PowerShell snap-ins matching the pattern
'Microsoft.TeamFoundation.PowerShell' were found. Check the pattern and then
try the command again.
The following code is included in the script before anything else:
if ((Get-PSSnapin -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue
}
When I start a new instance of the interactive PowerShell shell and run the script in that, everything works perfectly.
UPDATE
I get the same error with either of the following PowerShell executables (since I seem to recall the TFS snapin was 32-bit only):
C:\windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe
In cmd.exe, the following command produces the following output:
c:\ powershell -Command "get-pssnapin -registered | where { $_.Name -eq 'TfsBPAPowerShellSnapIn' }"
Name : TfsBPAPowerShellSnapIn
PSVersion : 2.0
Description : This is a PowerShell snap-in that includes Team Foundation Server cmdlets.
So, I've written a very minimal script, joke.ps1:
Add-PsSnapin TfsBPAPowerShellSnapIn
$server = Get-TfsServer tfsserver/DefaultCollection
And I run it:
c:\ powershell -File .\joke.ps1
The term 'Get-TfsServer' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\jmcnamara\PowerShell\broken.ps1:3 char:24
+ $server = Get-TfsServer <<<< gearys/DefaultCollection
+ CategoryInfo : ObjectNotFound: (Get-TfsServer:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Add-PsSnapin doesn't give me an error. But adding the snap-in doesn't make any of the snap-in's cmdlets visible to the rest of the script.
Allegedly, Add-PsSnapin adds a snap-in to the current session:
The Add-PSSnapin cmdlet adds registered Windows PowerShell snap-ins to
the current session. After the snap-ins are added, you can use the
cmdlets and providers that the snap-ins support in the current
session.
"You" can, eh? "You" who? Yeah, sure you can.
But how?
My question turns out to have been almost a duplicate of Is there no TFS Snapin for PowerShell on x64?, TFS Power Tools 2008 Powershell Snapin won't run in on 64-bit in Windows 2008 R2, and probably others.
I don't understand why different snap-ins were listed as "registered" the 32-bit PowerShell console vs running 32-bit powershell.exe (the WOW64 one is 32-bit) in cmd.exe, but whatever.
The answer appears to be here: The installer doesn't properly add the TFS snap-in to the Registry. The link shows you how to set it up to be usable from 64-bit PowerShell, but it appears that you need to do the same, at a different key, to make it usable from 32-bit PowerShell outside of the PowerShell console. So you paste the following into tfskludge.reg, double click it, and it should make the snap-in available in both PowerShells:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.TeamFoundation.PowerShell]
"PowerShellVersion"="2.0"
"Vendor"="Microsoft Corporation"
"Description"="This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"VendorIndirect"="Microsoft.TeamFoundation.PowerShell,Microsoft"
"DescriptionIndirect"="Microsoft.TeamFoundation.PowerShell,This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"Version"="10.0.0.0"
"ApplicationBase"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools"
"AssemblyName"="Microsoft.TeamFoundation.PowerTools.PowerShell, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
"ModuleName"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools\\Microsoft.TeamFoundation.PowerTools.PowerShell.dll"
"CustomPSSnapInType"="Microsoft.TeamFoundation.PowerTools.PowerShell.TFPSSnapIn"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.TeamFoundation.PowerShell]
"PowerShellVersion"="2.0"
"Vendor"="Microsoft Corporation"
"Description"="This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"VendorIndirect"="Microsoft.TeamFoundation.PowerShell,Microsoft"
"DescriptionIndirect"="Microsoft.TeamFoundation.PowerShell,This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"Version"="10.0.0.0"
"ApplicationBase"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools"
"AssemblyName"="Microsoft.TeamFoundation.PowerTools.PowerShell, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
"ModuleName"="C:\\Program Files (x86)\\Microsoft Team Foundation Server 2010 Power Tools\\Microsoft.TeamFoundation.PowerTools.PowerShell.dll"
"CustomPSSnapInType"="Microsoft.TeamFoundation.PowerTools.PowerShell.TFPSSnapIn"