I was given a powershell script by a coworker to try and figure out. I have very little expereince with it so I've gotten stuck.
We need to pull a user defined cmdlet from a .ps1 file form another part of the drive.
Normally you would do it something like this:
. .\scripts\thing.ps1
But we want to use an environmental variable set in command prompt to start the location. We have something like:
. $Env:JobDir\scripts\thing.ps1
But this returns the error
. : The term '\scripts\thing.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program.
Is there anyway to make something like this work?
You'd need to make it a string, otherwise it's interpreting the entire path as a variable.
"$Env:JobDir\scripts\thing.ps1"
or
$Env:JobDir + "\scripts\thing.ps1"
You can do something like this:
# build the path to the job
$job = Join-path -Path $Env:JobDir -ChildPath "scripts\thing.ps1"
# execute the job
$job
or
.$("$Env:JobDir\scripts\thing.ps1")
I am fairly new to powershell and I am trying to create a script that executes a .exe file. I can execute them on my machine no problem because the folder path is hard coded. The problem is that if I shift this script to another computer, the .exe it calls might be located in a different folder structure. Example
My computer:
D:\Folder1\subfolder\RunMe.exe
Client computer might be
D:\RunMe\subfolder\RunMe.exe
I just need it to execute the RunMe.exe no matter where it is. Is there a way to do this in powershell?
# 1. Get the location of RunMe.exe
$RunMe = Get-ChildItem -Path d:\* -Include RunMe.exe -Recurse;
# 2. Invoke RunMe.exe
Start-Process -FilePath $RunMe[0].FullName -Wait -NoNewWindow;
Is there any other way except $MyInvocation.InvocationName in powershell to get the script name?
As i need to turn my script in an exe and in that case it doesnt work on that exe.
I'm assuming since you convert the powershell script to an executable that you are after the location of the executable. You can get it this way:
[Environment]::GetCommandLineArgs()[0]
If you want something that works within and outside of ISE you can use
$MyInvocation.InvocationName
Since full paths and .\YourScript.ps1 can be returned you can parse the name with:
[Regex]::Match( $MyInvocation.InvocationName, '[^\\]+\Z', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::SingleLine ).Value
I have a PowerShell script that does some stuff using the script’s current directory. So when inside that directory, running .\script.ps1 works correctly.
Now I want to call that script from a different directory without changing the referencing directory of the script. So I want to call ..\..\dir\script.ps1 and still want that script to behave as it was called from inside its directory.
How do I do that, or how do I modify a script so it can run from any directory?
Do you mean you want the script's own path so you can reference a file next to the script? Try this:
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-host "My directory is $dir"
You can get a lot of info from $MyInvocation and its properties.
If you want to reference a file in the current working directory, you can use Resolve-Path or Get-ChildItem:
$filepath = Resolve-Path "somefile.txt"
EDIT (based on comment from OP):
# temporarily change to the correct folder
Push-Location $dir
# do stuff, call ant, etc
# now back to previous directory
Pop-Location
There's probably other ways of achieving something similar using Invoke-Command as well.
There are answers with big number of votes, but when I read your question, I thought you wanted to know the directory where the script is, not that where the script is running. You can get the information with powershell's auto variables
$PSScriptRoot # the directory where the script exists, not the
# target directory the script is running in
$PSCommandPath # the full path of the script
For example, I have a $profile script that finds a Visual Studio solution file and starts it. I wanted to store the full path, once a solution file is started. But I wanted to save the file where the original script exists. So I used $PsScriptRoot.
If you're calling native apps, you need to worry about [Environment]::CurrentDirectory not about PowerShell's $PWD current directory. For various reasons, PowerShell does not set the process' current working directory when you Set-Location or Push-Location, so you need to make sure you do so if you're running applications (or cmdlets) that expect it to be set.
In a script, you can do this:
$CWD = [Environment]::CurrentDirectory
Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
## Your script code calling a native executable
Pop-Location
# Consider whether you really want to set it back:
# What if another runspace has set it in-between calls?
[Environment]::CurrentDirectory = $CWD
There's no foolproof alternative to this. Many of us put a line in our prompt function to set [Environment]::CurrentDirectory ... but that doesn't help you when you're changing the location within a script.
Two notes about the reason why this is not set by PowerShell automatically:
PowerShell can be multi-threaded. You can have multiple Runspaces (see RunspacePool, and the PSThreadJob module) running simultaneously withinin a single process. Each runspace has it's own $PWD present working directory, but there's only one process, and only one Environment.
Even when you're single-threaded, $PWD isn't always a legal CurrentDirectory (you might CD into the registry provider for instance).
If you want to put it into your prompt (which would only run in the main runspace, single-threaded), you need to use:
[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem
This would work fine.
Push-Location $PSScriptRoot
Write-Host CurrentDirectory $CurDir
I often used the following code to import a module which sit under the same directory as the running script. It will first get the directory from which powershell is running
$currentPath=Split-Path ((Get-Variable
MyInvocation -Scope
0).Value).MyCommand.Path
import-module "$currentPath\sqlps.ps1"
I made a one-liner out of #JohnL's solution:
$MyInvocation.MyCommand.Path | Split-Path | Push-Location
Well I was looking for solution for this for a while, without any scripts just from CLI. This is how I do it xD:
Navigate to folder from which you want to run script (important thing is that you have tab completions)
..\..\dir
Now surround location with double quotes, and inside them add cd, so we could invoke another instance of powershell.
"cd ..\..\dir"
Add another command to run script separated by ;, with is a command separator in powershell
"cd ..\..\dir\; script.ps1"
Finally Run it with another instance of powershell
start powershell "cd..\..\dir\; script.ps1"
This will open new powershell window, go to ..\..\dir, run script.ps1 and close window.
Note that ";" just separates commands, like you typed them one by one, if first fails second will run and next after, and next after... If you wanna keep new powershell window open you add -noexit in passed command . Note that I first navigate to desired folder so I could use tab completions (you couldn't in double quotes).
start powershell "-noexit cd..\..\dir\; script.ps1"
Use double quotes "" so you could pass directories with spaces in names e.g.,
start powershell "-noexit cd '..\..\my dir'; script.ps1"
I'm running a .PS1 script as part of a larger script to get computers to join our domain semi-automatically. The .PS1 is created from variables and ends up looking like this:
add-computer -DomainName ourdomain.com - OUPath "OU=Computers,OU=Somewhere,DC=OURDOMAIN,DC=COM" -Cred OD\syswdg
While this works fine, I would like to be able to output the restult of this to a text file so that I can check if this has worked sccessfully or not before proceeding to do other stuff in the script. Is there any way to get the results of this output to a file? I've tried using the Out-File Cmdlet, the Tee-Object Cmdlet and tried running the joindomain.PS1 from another PS1 like joindomain.ps1 > outputfile.txt and while they all produce a file, it is always empty. Any help appreciated.
By default, there is no output when the cmdlet is successful. Use -Passthru and -Verbose if you want to see the output of this cmdlet.