Paths from environmental variables not available in Powershell - powershell

So I have installed the Team Foundation Server PowerShell Tools, and verified they exist, but the executables (TFPT.exe) do not appear to be available in powershell.
Looking at $env:path (and looking at the path variable through System Properties) I see that the end of the path variable looks like this:
$env:Path = {other variables};%TFSPowerToolDir%;%BPADir%;.;
System Properties Enviromental Variables = {other variables};%TFSPowerToolDir%;%BPADir%
When I look at $env:TFSPowerToolDir I get C:\Program Files (x86)\Microsoft Team Foundation Server 2013 Power Tools\, so that seems correct.
But if I try to run tfpt I get the error "The term 'tfpt.exe' is not recognixed as the name of a cmdlet...
If I first do cd $env:TFSPowerToolDir and the run tfpt it works fine. So the environmental variable is correct. But it doesn't seem to get placed in the path.
Any ideas on how to fish this?

Can't replicate the problem here, actually. The problem seems to be that other environment variables are not expanded in $Env:PATH here, but in a quick test PowerShell did so for me reliably.
You could try to work around the problem by manually expanding environment variables in your profile script. E.g. with something like the following:
$Env:PATH = [regex]::Replace($Env:PATH, '%([^%]+)%', {
param($m)
$n = $m.Groups[1].Value
Get-Content -Raw Env:\$n
})

Related

How to permanently remove a UNC path from $env:PSModulePath for PowerShell?

Where I work, users have their folders redirected to a UNC path to save data. This seems to have affected my PowerShell because every time I start up powershell, it attempts to load modules from the UNC path and it takes a long time. This also affects how I use cmdlets because it tries to search the UNC path for cmdlet context.
When I look at the output of $env:PSModulePath I can see the UNC directory. But it doesn't show up in System's Environment Variables dialog editor.
How can I get rid of this so that Powershell doesn't keep looking for module support from the UNC directory? I understand that I can edit an existing sessions $env:PSModulePath, but I want it gone forever.
The Microsoft documentation page about_PSModulePath explains it. By default, PowerShell builds the $env:PSModulePath value by concatenating:
The user's "Documents" folder, likely the UNC path you are mentioning.
The contents of the PSModulePath system environment variable.
You can find out the path of the "Documents" folder as follows:
[Environment]::GetFolderPath('MyDocuments')
If you define a user-level environment variable PSModulePath in addition to the system environment variable PSModulePath, it will replace your "Documents" folder in $env:PSModulePath, which won't contain the UNC path anymore.
To permanently change the PSModulePath environment variable, you can use the .NET method SetEnvironmentVariable on the System.Environment class.
Example:
[Environment]::SetEnvironmentVariable("PSModulePath", "Some_Path", "Machine")
Keep in mind, this will overwrite what you had before on this variable. So make sure before you run the method as the PSModulePath will certainly have paths that you might need.
Also, if your company is using GPOs to set the PSModulePath variable, then the only way to remove the UNC path is to talk to your administrator that handles that.
I don't know why it is not shown in your system variables GUI. You should be able to remove it with something along these lines:
$yourvalueyouwanttodelete = 'somepath'
$oldval = [environment]::GetEnvironmentVariable("PSModulePath")
$arr_oldval = $oldval -split ";"
$arr_newval = $arr_oldval | ? {$_ -ne $yourvalueyouwanttodelete}
$newval = $arr_newval -join ";"
[environment]::SetEnvironmentVariable("PSModulePath", $newval)
The way I resolved this was to set the Module Path in the All users profile
For me $PROFILE.AllUsersAllHosts returned:
C:\Program Files\PowerShell\7\profile.ps1
I created that file and added the following:
$ModulePath = "c:\program files\powershell\7\Modules"
[Environment]::SetEnvironmentVariable("PSModulePath", $ModulePath)
I ran into the same issue after removing PowerShell 7 from my device. What appears to be happening is that the PSModulePath variable to My Documents is removed from the environment variables under Advanced System Settings. Powershell then uses the UNC path, which is configured by group policy.
The solution, that worked for me was to add a new Environment Variable called PSModulePath with the value of C:\Users\YourUserNameHere\Documents. Now powershell has a place to look for those PS Modules.

Powershell add to path, temporarily

I'm trying to write a simple PowerShell script to deploy a Visual Studio ASPNET Core 1 project.
Currently, in a batch file i can say
Path=.\node_modules\.bin;%AppData%\npm;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External;%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External\git
That will modify the path variable for the duration of the session... for the life of me I can't figure out how to do this simple thing in powershell.
Can someone help me translate this into powershell?
TIA!
Option 1: Modify the $env:Path Variable
Append to the Path variable in the current window:
$env:Path += ";C:\New directory 1;C:\New directory 2"
Prefix the Path variable in the current window:
$env:Path = "C:\New directory 1;C:\New directory 2;" + $env:Path
Replace the Path variable in the current window (use with caution!):
$env:Path = "C:\New directory 1;C:\New directory 2"
Option 2: Use the editenv Utility
I wrote a Windows command-line tool called editenv that lets you interactively edit the content of an environment variable. It works from a Windows console (notably, it does not work from the PowerShell ISE):
editenv Path
This can be useful when you want to edit and rearrange the directories in your Path in a more interactive fashion, and it affects only the current window.
You can just use $env:Path, but if you're anxious that that isn't explicit enough, you can use System.Environment.SetEnvironmentVariable():
[System.Environment]::SetEnvironmentVariable('Path',$Value,[System.EnvironmentVariableTarget]::Process);
And GetEnvironmentVariable() can explicitly retrieve:
[System.Environment]::GetEnvironmentVariable('Path',[System.EnvironmentVariableTarget]::Process);
[System.Environment]::GetEnvironmentVariable('Path',[System.EnvironmentVariableTarget]::Machine);
[System.Environment]::GetEnvironmentVariable('Path',[System.EnvironmentVariableTarget]::User);

adding cygwin bin directory to powershell path environment variable ... cygwin within powershell

Powershell is great for scripting. But when it comes to everyday use, certain things can be a huge PITA!!
so i thought it would be great if i could do something like this in my profile.ps1:
$env:path = "$($env:path);c:\cygwin\bin"
to get access to utilities like tar, zip, etc... but this doesn't work. The variable looks right when i do:
PS > $env:path
but when i try to do, say,
PS > unzip foo.zip
i get a command not found type error.
WTF PowerShell!?
edit: great answers! I looked at it with fresh eyes this morning and realized that I just needed to spell 'cygwin' correctly! now I don't have to switch back and forth between two consoles. It should be noted for anyone who uses this tip that your path in powershell is evaluated in order - if you put c:\cygwin\bin at the end of the $env:path variable, it will be searched last, so it won't interfere with existing powershell aliases / cmdlets.
It worked for me:
To set your profile:
$command = '$env:path = $env:path + ";C:\Program Files\Notepad++"'
$command | Out-File -FilePath $PROFILE -Append -Encoding UTF8
Or just the current shell:
$env:path = $env:path + ";C:\Program Files\Notepad++"
Using $env:path to add the cygwin bin to PATH should work as long as you are trying to use it in the same Powershell session. If you open a new console or if you close and open Powershell, it will not be persisted. Otherwise, what you are doing should work. Make sure you are indeed adding the correct path. If you want to persist the changes, add the line to your $profile.
Also, try using the Mingw / Msys / Msysgit utils. I find Mingw to be more lightweight than cygwin ( if you are using cygwin just to get some of these utils.)
PowerShell by default is only going to modify its local copy of PATH. When you run an external command, they aren't going to see the local environment variables.
Per this TechNet article, you can fall back to the .NET static method SetEnvironmentVariable to do this at the user level if you want this to be a permanent change:
[Environment]::SetEnvironmentVariable("TestVariable", "Test value.", "User")

Powershell import-module doesn't find modules

I'm learning PowerShell and I'm trying to build my own module library.
I've written a simple module XMLHelpers.psm1 and put in my folder $home/WindowsPowerShell/Modules.
When I do:
import-module full_path_to_XMLHelpers.psm1
It works. But when I do:
import-module XMLHelpers
It doesn't work and I get the error:
Import-Module : The specified module 'xmlhelpers' was not loaded because no valid module file was found in any module directory.
I've checked that the environment variable PSModulePath contains this folder. As it is a network folder, I've also tried to move it to a local folder and to modify PSModulePath but without success
$env:PSModulePath=$env:PSModulePath+";"+'C:\local'
Any idea on what could cause this issue?
The module needs to be placed in a folder with the same name as the module. In your case:
$home/WindowsPowerShell/Modules/XMLHelpers/
The full path would be:
$home/WindowsPowerShell/Modules/XMLHelpers/XMLHelpers.psm1
You would then be able to do:
import-module XMLHelpers
1.This will search XMLHelpers/XMLHelpers.psm1 in current folder
Import-Module (Resolve-Path('XMLHelpers'))
2.This will search XMLHelpers.psm1 in current folder
Import-Module (Resolve-Path('XMLHelpers.psm1'))
I think that the Import-Module is trying to find the module in the default directory C:\Windows\System32\WindowsPowerShell\v1.0\Modules.
Try to put the full path, or copy it to C:\Windows\System32\WindowsPowerShell\v1.0\Modules
I experienced the same error and tried numerous things before I succeeded. The solution was to prepend the path of the script to the relative path of the module like this:
// Note that .Path will only be available during script-execution
$ScriptPath = Split-Path $MyInvocation.MyCommand.Path
Import-Module $ScriptPath\Modules\Builder.psm1
Btw you should take a look at http://msdn.microsoft.com/en-us/library/dd878284(v=vs.85).aspx which states:
Beginning in Windows PowerShell 3.0, modules are imported automatically when any cmdlet or function in the module is used in a command. This feature works on any module in a directory that this included in the value of the PSModulePath environment variable ($env:PSModulePath)
I had this problem, but only in Visual Studio Code, not in ISE. Turns out I was using an x86 session in VSCode. I displayed the PowerShell Session Menu and switched to the x64 session, and all the modules began working without full paths. I am using Version 1.17.2, architecture x64 of VSCode. My modules were stored in the C:\Windows\System32\WindowsPowerShell\v1.0\Modules directory.
Some plugins require one to run as an Administrator and will not load unless one has those credentials active in the shell.
My finding with PS 5.0 on Windows 7: $ENV:PsModulePath has to end with a . This normally means it will load all modules in that path.
I'm not able to add a single module to $env:PsModulePath and get it to load with Import-Module ExampleModule. I have to use the full path to the module. e.g. C:\MyModules\ExampleModule. I am sure it used to work.
For example:
Say I have the modules:
C:\MyModules\ExampleModule
C:\MyModules\FishingModule
I need to add C:\MyModules\ to $env:PsModulePath, which will allow me to do
Import-Module ExampleModule
Import-Module FishingModule
If for some reason, I didn't want FishingModule, I thought I could add C:\MyModules\ExampleModule only (no trailing \), but this doesn't seem to work now. To load it, I have to Import-Module C:\MyModules\ExampleModule
Interestingly, in both cases, doing Get-Module -ListAvailable, shows the modules, but it won't import. Although, the module's cmdlets seem to work anyway.
AFAIK, to get the automatic import to work, one has to add the name of the function to FunctionsToExport in the manifest (.psd1) file. Adding FunctionsToExport = '*', breaks the auto load. You can still have Export-ModuleMember -Function * in the module file (.psm1).
These are my findings. Whether there's been a change or my computer is broken, remains to be seen. HTH
try with below on powershell:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
import-module [\path\]XMLHelpers.psm1
Instead of [] put the full path
Full explanation of this and that
First of all check Your account type,some imports are not allowed to normal partner accounts.

How to give the path as a parameter or a variable in powershell

I have written a powershell script. the code has paths related to only my PC.
Now the same code cannot be executed by another person on his machine because the path is diff. Therefore please let me know a way where my code can work on all machines.
It depends on the paths. If they're to programs in \Program Files perhaps you can use the environment variable $env:ProgramFiles in your path spec. You can also parameterize your script to take the path like so:
param($path)
# rest of script ...
Note that the param() statement must be the first non-comment line in your script.
You could also use the special $MyInvocation variable available to running scripts. It has access to the path the script was executed from, among other things.
For example a script I use has this line:
$InputCSV = (split-path $myinvocation.mycommand.path) + "\filename.csv"
Which means no matter where the script is run from it will know to grab the CSV file from the same place.