I have a script file script1.ps1 that is passing an argument to another script file script2.ps1 in a psexec.exe command, the problem is that when i run this file in my system, it executes perfectly, but when running it by a server, it says the file path does not exist. Here is the code
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
$path = $dir + '\Script2\script2.ps1'
$args = 1
$Query = 'psexec.exe \\' + $ip + ' /accepteula cmd /c "powershell -noninteractive -file $path -id $args"'
Invoke-Expression $Query
So sorry that i currently don't have screenshot of the error message, but it is saying file does not exist. I want to know is there an special way to declare a file path? I have tried this as well, \\$computer1\C$\Folder\Script2\script2.ps1 but doesn't work, seems like i am doing something wrong in it.
Related
$password = ConvertTo-SecureString “Password+++” -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("Admin", $password)
$FileLocale = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
Write-Output $FileLocale
$AntFile = "$FileLocale\StartApps.ps1"
Write-Output $AntFile
Start-Process PowerShell.exe -ArgumentList "-command &$AntFile -UserCredential $Cred"
Hi, that code works in .ps1, I call the other script, and he makes his job. But when I transform it in .exe with the help of ps2exe, he doesn't do his job anymore. As admin or not. It's not the first time I use that start-process, but it's the first time I use a variable as a target for the command. Do anyone know what go wrong between the ps1 and exe ?
Thanks
While an executable compiled with ps2exe uses a .ps1 file as input, at runtime no actual .ps1 file is involved, which is why PowerShell's command-reflection variables cannot tell you anything about a running script file.
When running an actual .ps1 file, you'd use the following about_Automatic_Variables:
$PSCommandPath contains the the executing script file's full file path.
$PSScriptRoot contains the script file's full directory path (i.e. the full path of the directory in which the script file is located).
In a ps2exe-compiled executable (.exe), where these variables have no values, you can use the following instead:
[Environment]::GetCommandLineArgs()[0] contains the executable file's full file path.
Split-Path -LiteralPath ([Environment]::GetCommandLineArgs()[0]) contains the executable file's full directory path.
Applied to your code - assuming that a separate StartApp.ps1 file is present alongside your .exe file:[1]
$FileLocale = Split-Path -LiteralPath ([Environment]::GetCommandLineArgs()[0])
$AntFile = Join-Path $FileLocale StartApps.ps1
If you want to make your code work in both invocation scenarios - the original .ps1 file directly as well as the compiled .exe file - use the following:
$FileLocale =
if ($PSScriptRoot) { $PSScriptRoot }
else { Split-Path -LiteralPath ([Environment]::GetCommandLineArgs()[0]) }
$AntFile = Join-Path $FileLocale StartApps.ps1
[1] Note that at runtime no information is available about where the original .ps1 file that served as compile-time input was originally located - only that file's content becomes part of the .exe file.
I have to find and then execute a .exe file from a script deployed by our asset management software. Currently it looks like this:
Set-Location $PSScriptRoot
$proc = (Start-Process -FilePath "C:\Program Files (x86)\software\software name\Uninstall.exe" -ArgumentList "/S /qn" -Wait -PassThru)
$proc.WaitForExit()
$ExitCode = $proc.ExitCode
Exit($ExitCode)
As far as I understand the location for the location for the file is set and some users do not have it there hence why it fails.
So I understand that you can search for a program with
Get-ChildItem C:\Program Files (x86)\software\
And execute with Start-process -Filepath
But do I simply combine that with a | or is there an easier way/will it even work.
As commenter suggested, you can use Test-Path to test if a path exists:
$uninstallPath = Join-Path ${env:ProgramFiles(x86)} 'software\software name\Uninstall.exe'
if( Test-Path $uninstallPath ) {
$proc = Start-Process -FilePath $uninstallPath -ArgumentList '/S /qn' -Wait -PassThru
$proc.WaitForExit()
$ExitCode = $proc.ExitCode
Exit $ExitCode
}
I've also made the code more robust by avoiding the hardcoded "Program Files (x86)" directory, using an environment variable. Because of the parentheses in the name of the env var, it must be enclosed in curly braces.
For added robustness, you may read the path of the uninstall program from the registry, as detailed by this Q&A. If you are lucky, the program even stores a QuietUninstallString in the registry, which gives you the full command line for silent uninstall.
I recently wrote a script and want to share it with my colleagues. It’s a simple copy and paste program that creates log-files after each run. The problem is that I used this: start transcript -Path C:\Users…
The program works fine but if anyone else runs the script it won’t be able to create log-files, since the directory is a copy of mine.
Now to my question: Is there anyway that the program can find out the directory where each user saved the script so it can create a sub-folder in that directory and then dump the logs in there?
Thank you in advance
The path to the folder containing the currently executing script can be obtained through the $PSScriptRoot automatic variable:
Start-Transcript -OutputDirectory $PSScriptRoot
Here's how I record PowerShell sessions using the Start-Transcript cmdlet. It creates a log file, where the script is run from.
#Log File Paths
$Path = Get-Location
$Path = $Path.ToString()
$Date = Get-Date -Format "yyyy-MM-dd-hh-mm-ss"
$Post = "\" + (Get-Date -Format "yyyy-MM-dd-hh-mm-ss") + "-test.log"
$PostLog = $Path + $Post
$PostLog = $PostLog.ToString()
#Start Transcript
Start-Transcript -Path $PostLog -NoClobber -IncludeInvocationHeader
#Your Script
Get-Date
#End Transcript
Stop-Transcript -ErrorAction Ignore
I have a script that we use that is in Powershell however I need the script to be able to find the files that it needs to install an application dynamically as users can copy the folder to any folder on their computer. Currently I have the below code set, I guess my question is, if the script is in the same folder as the install files. How do I tell powershell to just look in the directory that its being ran from for the install files?
$Install = "C:\Other Folder\File.msi"
$InstallArg = "/quite /norestart"
Start-Process '
-FilePath $Install '
-ArgumentList $InstallArg '
-PassThru | Wait-Process
Any help would be appreciated. Thank you.
Update, I found that I have to be in the directory the script is in. However since we have to run ISE with admin credentials it automatically defaults to C:\Windows\System32 as the directory powershell is looking in regardless if I tell it to open the script. If that is the case how can I tell it to look where the script is located so that it can find the files that it needs?
I have found my answer below is how I got it to work with our current situation. Thank you Thomas for the help!
$ScriptLocation = Get-ChildItem -Path C:\Users -Filter Untitled2.ps1 -Recurse | Select Directory
cd $ScriptLocation.Directory
$Install = ".\Install.msi"
$InstallArg = "/quite /norestart"
Start-Process '
-FilePath $Install '
-ArgumentList $InstallArg '
-PassThru | Wait-Process
Define a relative path:
$Install = ".\File.msi"
If you are not running the script inside the directory, where the script itself and the executable are stored, you will have to determine the absolute path to it. With PowerShell 3+ you can easily determine the directory, where your script is stored, using the $PSScriptRoot variable. You could define your $Install variable like this:
$Install = Join-Path -Path $PSScriptRoot -ChildPath "File.msi"
Thank you so much for your help everyone! I accidentally stumbled upon the perfect solution.
# Set active path to script-location:
$path = $MyInvocation.MyCommand.Path
if (!$path) {
$path = $psISE.CurrentFile.Fullpath
}
if ($path) {
$path = Split-Path $path -Parent
}
Set-Location $path
I am trying to run an application from C:\Program Files\APP\app.exe with the application built in commands. When I run from the command prompt, I can get the result I wanted. But I would like to use the script which will check other components of servers along with this one to avoid running this command manually. I tried both of the mentioned scripts below & I am not getting any output. It just opens a command prompt window, runs the result, and closes the command prompt,but I would like to get the output in an output file. Any suggestions? Please let me know.
$Output = "C:\Information.txt"
Start-Process -FilePath "C:\Program Files\APP\app.exe" -ArgumentList "query mgmtclass" | Out-File $Output
Additionally, I also tried -
$Output = "C:\Information.txt"
Start-Process -FilePath "C:\Program Files\APP\app.exe" -PipelineVariable "query mgmtclass" | Out-File $Output
I was also thinking that I can write a batch file & get output written in the temp directory & get those output using the command mentioned below -
Get-Content -Path 'C:\Program Files\tivoli\tsm\baclient\dsmerror.log' | select-object -last 15
Can you try using the RedirectStandardOutput parameter instead of | Out-File:
$Output = "C:\Information.txt"
Start-Process -FilePath "C:\Program Files\APP\app.exe" -PipelineVariable "query mgmtclass" -RedirectStandardOutput $Output
Update:
The error you are getting ("Missing an argument") means exactly what it says. I can't see the line of code you ran to get the error, but I can replicate by omitting the value of RedirectStandardOutput. This example uses splatting so the line of code is not so long, and you can see more clearly what RedirectStandardOutput is:
$Output = "C:\Information.txt"
#{
FilePath = "C:\Program Files\APP\app.exe"
PipelineVariable = "query mgmtclass"
RedirectStandardOutput = $Output
} | % { Start-Process #_ }