In PowerShell I can echo the value of %TEMP% using the command $Env:TEMP. Here is the output on my machine:
PS> $Env:temp
C:\Users\IAIN~1.COR\AppData\Local\Temp
When I try to change to the directory using the cd command, I receive this error:
PS> cd $Env:temp
Set-Location : An object at the specified path C:\Users\IAIN~1.COR does not exist.
At line:1 char:3
+ cd <<<< $Env:temp
+ CategoryInfo : InvalidArgument: (:) [Set-Location], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.SetLocationCommand
I suspect that PowerShell is interpreting the 8.3 file name literally. The long file name of the directory is C:\Users\iain.CORP\AppData\Local\Temp. When I try cd C:\Users\Iain.CORP\AppData\Local\Temp, the directory changes successfully.
How can I open the path in $Env:TEMP using PowerShell? Do I have to have the long file name first?
You don't need to access the %TEMP% environment variable directly.
.NET provides a GetTempPath method as a more general solution.
$TempDir = [System.IO.Path]::GetTempPath()
cd $TempDir
On my machine, this changes to the directory C:\Users\Iain.CORP\AppData\Local\Temp.
Remarks from the documentation:
This method checks for the existence of environment variables in the
following order and uses the first path found:
The path specified by the TMP environment variable.
The path specified by the TEMP environment variable.
The path specified by the USERPROFILE environment variable.
The Windows directory.
Thanks to Joe Angley for sharing the technique.
Open $env:temp by first resolving its fullname like this:
cd (gi $env:temp).fullname
cd $env:temp
This worked for me.
Related
I have a batch file I'm executing on Windows 10 through the "Deployment and Imaging Tools Environment"
powershell Mount-DiskImage ./%WORKSPACE%/W10-LTSB.iso
The environment variable WORKSPACE has been checked and contains a valid path that exists as does the file W10-LTSB.iso, however when this command is executed it results in:
Mount-DiskImage: The system cannot find the path specified.
At line:1 char:1
+ Mount-DiskImage ./CA20-4002-OperatingSystem-AIMB-216/W10-LTSB.iso
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (MSFT_DiskImage:ROOT/Microsoft/.../MSFT_DiskImage) [Mount-DiskImage], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070003,Mount-DiskImage
Everything looks valid and has been checked many times, what does this message mean?
When a path starts with a dot/period ., it refers to the current directory. When a shell session starts, its current directory is configuration dependent.
For example, try running a Powershell session. It should default in c:\Users\<username>. Run a Powershell as admin and it usually defaults in C:\WINDOWS\system32.
When mounting a disk image with a path beginning with a dot
powershell Mount-DiskImage ./%WORKSPACE%/W10-LTSB.iso
will tell Mount-DiskImage to look the file from its current directory's subdir. Should the current directory be unexpected, Powershell's looking the file from wrong a place.
As for a solution, use absolute paths, or make sure the file is located in a path that's available via current directory (whatever it is).
I've currently got a script that:
Loops through some files
Checks the name of the file
If there is no directory for the file it will create one
Moves the file into the directory
The moving logic works fine. However if a directory does not exist I am given this error (the path is valid, except it does not exist)
C:\Users\User\Documents\Directory\FileName : The term 'C:\Users\User\Documents\
Directory\FileName' 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 line:1 char:1
C:\Users\User\Documents\Directory\FileName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\User\Documents\Directory\FileName) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
The curious part is that it does actually create the folder - however it crashes my script.
Here's the problem part of the script
function CanCreate($dir) {
return !(Test-Path $dir)
}
if (CanCreate($fullDestinationPath)) {
New-Item $fullDestinationPath -ItemType Directory
}
md/mkdir behave differently to New-Item in that they do crash the script, however New-Item prints the error and continues (script seems to finish its job).
Edit:
The issue seems to stem from the fact that I am calling the script from another script.
$ScriptPath = "C:\Powershell Scripts\script.ps1"
& $ScriptPath | Invoke-Expression
The issue was with the fact that I was using | Invoke-Expression to trigger the script.
Simply calling & $ScriptPath, omitting the | Invoke-Expression, was enough to trigger the script.
Thanks everyone.
I wrote a script in PowerShell and I am having various success calling Image Magick's montage.exe on different computers. The computer on which I wrote the script has no problem executing the 'montage' command, however on another computer with IM Installed the script errors out:
montage : The term 'montage' 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 \\Server\Contact_Sheet_Local.ps1:51 char:9
+ montage -verbose -label %t -pointsize 20 -background '#FFFFFF ...
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (montage:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I have tried using montage.exe and even tried the entire path C:\Program Files\ImageMagick-7.0.3-Q16\montage.exe. Additionally I tried setting the directory first:
Set-Location -Path 'C:\Program Files\ImageMagick-7.0.3-Q16'
montage...
Each time on a particular computer this fails. I have tried with IM versions 7.0.3-Q16 and 6.9.1-6-Q8 both x64 as both computers are x64
In the past, I have created scripts in .bat that use ImageMagick and I had to define the full path to the .exe as I mentioned above. But this doesn't seem to help in PowerShell.
Does anyone have any advice or experience with this problem?
If your path has spaces, it will fail if you're just trying to execute based on that. You'll want to utilize the dot operator
$Exe = 'C:\Program Files\ImageMagick-6.9.1-6-Q8\montage.exe'
If (-not (Test-Path -Path $Exe))
{
$Exe = 'C:\Program Files\ImageMagick-7.0.3-Q16\montage.exe'
}
. $Exe -arg1 -etc
PowerShell does not execute programs in the current directory by default. If you want to run an executable that's sitting in the current directory, prefix the executable's name with .\ or ./. Example:
Set-Location "C:\Program Files\ImageMagick-7.0.3-Q16"
.\montage.exe ...
If you have an executable's name in a string or string variable and you want to execute it, you can do so using the & (call or invocation) operator:
& "C:\Program Files\ImageMagick-7.0.3-Q16\montage.exe" ...
If you specify a path and filename that doesn't contain spaces, the & operator isn't required; example:
C:\ImageMagick\montage.exe ...
You could also write it this way:
& C:\ImageMagick\montage.exe ...
If you have an executable's filename in a string variable and you want to execute it, use &; example:
$execName = "C:\Program Files\ImageMagick-7.0.3-Q16\montage.exe"
& $execName ...
I am adding a UNC path, like "\\server\share\modules" to the user session env variable PSModule like this:
$env:PSModulePath = $env:PSModulePath + ";\\server\share\modules"
But, when I try to load a module from this path, I get an error
PS C:\> Import-Module WS_XML_MODULE
Import-Module : The specified module 'WS_XML_MODULE' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ Import-Module WS_XML_MODULE
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (WS_XML_MODULE:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
Listing all the available modules, which should show the UNC path available modules, doesn't show me any of the UNC folder modules...
Get-Module -listavailable
Anybody knows why?
Thanks
Go this working...
I took a look at the system modules folder and the syntax of the folders and files are exacly the same, with dots separating words like Microsoft.Powershell.Something
I then changed the name of the PSM1 file to the same and got them into folder with the same name and BAmm.. in a heartbeat loaded all my modules.
Place the "WS_XML_MODULE.psm1 and WS_XML_MODULE.psd1" in the folder named "WS_XML_MODULE".
Make sure "WS_XML_MODULE" folder is located in "\\server\share\modules"
Note: Don't include the Module name in Path
I have the following code in a powershell script. And I have file 7za.exe in the same directory of the script.
param($sql)
$temp = [System.IO.Path]::GetTempFileName()
Invoke-Sqlcmd -ServerInstance sqlserver1 $sql | ConvertTo-Csv > $temp
.\7za.exe a '$temp.zip' '$temp'
However, it got the following error. What's the right approach to execute an executable in the same folder right after invoke-sqlcmd?
SQL Server PowerShell provider error: Path SQLSERVER:\7za.exe does not exist. Please specify a valid path.
+ CategoryInfo : OperationStopped: (:) [], GenericProviderException
+ FullyQualifiedErrorId : Microsoft.SqlServer.Management.PowerShell.GenericProviderException
+ PSComputerName : localhost
If you look at the path in the error message, it is "SQLSERVER:\7za.exe" -- so the current working directory for the instance of PowerShell running this script (which you can get using the automatic variable $pwd) is SQLSERVER:\, which is the PSDrive created by the SQL module\snap-in that must be loaded to run the Invoke-SqlCmd cmdlet.
PowerShell scripts do NOT use their current location as the current working directory by default. In PowerShell version 3 and later, however, you can get the script's directory using the automatic variable $PSScriptRoot. In earlier versions, you can generate $PSScriptRoot yourself with:
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition
Then you could use this variable in your script like so:
& (Join-Path $PSScriptRoot '7za.exe') "$temp.zip" "$temp"
Note that I used double quotes around the $temp variable, so that PowerShell would automatically expand the variable into the correct name.
#jbsmith is right about what path to use. Contributing to this issue is that the SQLPS module changes the current directory to SQLSERVER: when it is imported.