I have tried with the command
if (-not (Get-Command Expand-7Zip -ErrorAction Ignore)) {
>> Install-Package -Scope CurrentUser -Force 7Zip4PowerShell > $null
>> }
PS C:\Users\noufal p> Expand-7Zip C:\Amazon\abc123d-setup.tar C:\awsUsers\%USERNAME%\Downloads
But getting error => The path 'C:\Amazon\abc123d-setup.tar' either does not exist or is not a valid file system path.
I suspect the error message is wrong - i think its actually complaining about the output location? Couple of things jump out me:
c:\awsUsers\ - is this correct/does it exist?
%USERNAME% - probably should be $env:USERNAME (have you tried hard-coding a value and see if that works?)
Based on the above assumptions, you could try:
Expand-7Zip C:\Amazon\abc123d-setup.tar "C:\Users\$env:USERNAME\Downloads"
Or just cut out the middle-man and use 7z.exe directly:
start-process -FilePath "C:\Program Files\7-Zip\7z.exe" -ArgumentList #("x -ttar C:\path\to\a\archive.tar -oc:\path\to\output")
Related
what I'm trying to do is setting up aliases to run Windows Terminal from file browser in the current directory, as admin or regular user.
I'm not very familiar with powershell scripts and I'm trying to understand why my functions are called when the script is loaded instead of when the alias is called, which in turn runs terminals indefinitely..
Here is the script I wrote in $Profile :
$wtHere = "wt -d ."
function Run-Command{
param($Command)
Invoke-Expression $Command
}
function Run-As-Administrator{
param($Command)
Run-Command -Command "runas /user:administrator $Command"
}
set-alias -Name wtha -Value $(Run-As-Administrator -Command $wtHere)
set-alias -Name wth -Value $(Run-Command -Command $wtHere)
Quoting this excellent answer which explains really well what you're doing wrong:
PowerShell aliases do not allow for arguments.
They can only refer to a command name, which can be the name of a cmdlet or a function, or the name / path of a script or executable
And from the official Docs:
The Set-Alias cmdlet creates or changes an alias for a cmdlet or a command, such as a function, script, file, or other executable. An alias is an alternate name that refers to a cmdlet or command.
This should help you understand what is going:
$wtHere = "Hello world"
function Run-Command {
param($Command)
"$Command - Received on {0}" -f $MyInvocation.MyCommand.Name
}
function Run-As-Admin {
param($Command)
Run-Command ("From {0} - Command: $Command" -f $MyInvocation.MyCommand.Name)
}
Set-Alias -Name wtha -Value $(Run-As-Admin -Command $wtHere)
Set-Alias -Name wth -Value $(Run-Command -Command $wtHere)
Get-Alias wth, wtha | Select-Object Name, Definition
You're storing the "result" of your functions and not the functions definitions into your aliases. You can't store an expression such as Run-As-Admin -Command $wtHere as the Value of your Alias, it will be stored as literal, even if you run the alias you would see that PowerShell will run the result of your expression and fail:
wth: The term 'Hello world - Received on Run-Command' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
What you should do is as simple as:
Set-Alias -Name wtha -Value Run-As-Admin
Set-Alias -Name wth -Value Run-Command
Then you can interactively run:
PS /> wtha $wtHere
So I am trying to write a script that will check if the user has a certain module installed, and if it doesn't, to install it, then rerun itself.
When I try to run this, the script just keeps rerunning and trying to install. I have to use a setup.exe and I have it waiting for the window to cl
$mypath = $MyInvocation.MyCommand.Path
$Path = Split-Path $mypath -Parent
$Location = "$Path" + "\setup.exe"
if (Get-Module -ListAvailable -Name ActiveRolesManagementShell) {
Write-Host "QAD Is installed"
pause
}
else{
Write-Host "Installing QAD"
Start-Process $Location
Wait-Process -Name "setup"
Pause
$CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
Pause
}
Normally, modules are installed using Install-Module. Then you might need to tell PowerShell about it for the current session to be able to use it.
if (-not(Get-Module -ListAvailable -Name ActiveRolesManagementShell)) {
Install-Module ActiveRolesManagementShell
Import-Module ActiveRolesManagementShell # Might not be needed
}
# Add code that uses ActiveRolesManagementShell module
But with regards to ActiveRolesManagementShell, what version are you using?
The old Quest module was probably meant to work on PowerShell v2. And I can't find a current version...
I know this has many answers on internet. I tried many of the sample codes but didn't work for me.
My requirement:
I have a powershell file CreateLink.ps1 this creates a link for the source folder($source) in destination folder($destination) with given link name($link). All three values are passed as arguments to this file. If I execute these with Powershell CLI as
C:\codedeploy\UAT\CreateLink.ps1 -source C:\Deployments\UAT\ -destination C:\codedeploy\UAT\release -link publish
soft link name publish of destinatio path C:\codedeploy\UAT\release is created in source path works fine. Below is CreateLink.ps1 code:
param([parameter(mandatory=$true)]
$source,
$destination,
$link)
# Write-Host $source
# Write-Host $destination
if ($PSHOME -like "*SysWOW64*")
{
Write-Warning "Restarting this script under 64-bit Windows PowerShell."
# Restart this script under 64-bit Windows PowerShell.
# (\SysNative\ redirects to \System32\ for 64-bit mode)
& (Join-Path ($PSHOME -replace "SysWOW64", "SysNative") powershell.exe) -File `
(Join-Path $PSScriptRoot $MyInvocation.MyCommand) #args
# Exit 32-bit script.
Exit $LastExitCode
}
# Release Root path
$release_root="$source"
# Deployment Root path
$deployment_root="$destination"
$symlink="$link"
# Make a Symlink path
$pathLink="$release_root\$symlink"
# Delete Symlink if exists and create anew
if((Test-Path $pathLink) -ne 0)
{
Write-Output "Delete release Link: $pathLink<--"
# Powershell issue w/ Symlinks
# https://github.com/PowerShell/PowerShell/issues/621
# Fix: https://kristofmattei.be/2012/12/15/powershell-remove-item-and-symbolic-links/
# rm -r $pathLink -Force
$RMDIR = "/c rmdir $pathLink"
Start-Process cmd.exe -ArgumentList $RMDIR -Wait
}
$MKLINK = "/c mklink /D $pathLink $deployment_root"
Start-Process cmd.exe -ArgumentList $MKLINK -Wait
Now I need to call this powershell script file with arguments in a batch file after-deploy.bat in jenkins job. I tried below code:
Powershell.exe -executionpolicy remotesigned -File C:\codedeploy\UAT\CreateLink.ps1 -source C:\Deployments\UAT\ -destination C:\codedeploy\UAT\release -link publish
and
powershell -Command "&{ Start-Process powershell -ArgumentList '-File C:\codedeploy\UAT\CreateLink.ps1' -source C:\Deployments\UAT\ -destination C:\codedeploy\UAT\release -link publish -Verb RunAs}"
few other commands also didn't work for me. Any help on how to run this command with parameters from batch file would be appreciated. If possible please provide snippet of code.
Thanks in advance.
I'm using PowerShell remoting to execute an exe file on a remote server. The problem is that the exe needs to have its Working Directory set to the directory that the exe is in for it to run properly. If I run the exe locally (on the server) from a command prompt it works fine, and if I use Enter-PSSession (from my workstation) and then use Start-Process -FilePath [PathToExe] -WorkingDirectory [DirectoryPath] that works fine, but if I use Invoke-Command -ComputerName [Blah] -ScriptBlock [MyScriptBlock] or $session = New-PSSession -ComputerName [Blah]; Invoke-Command -Session $session -ScriptBlock [MyScriptBlock] (from my workstation) then the working directory does not get set.
This is what [MyScriptBlock] looks like:
$scriptBlock = {
param($version, $database)
$hubSyncronizerExeDirectoryPath = "C:\inetpubLive\ScheduledJobs\$version\"
$hubSyncronizerExePath = Join-Path $hubSyncronizerExeDirectoryPath 'Test.exe'
Set-Location -Path $hubSyncronizerExeDirectoryPath
Get-Location
Write-Output "$version $database"
Start-Process -FilePath $hubSyncronizerExePath -WorkingDirectory $hubSyncronizerExeDirectoryPath -ArgumentList '/database',$database
}
I've also tried using Invoke-Command instead of Start-Process, but it has the same effect; the Working Directory does not get set.
I've verified this by using the SysInternals Process Explorer, right-clicking on the process and choosing Properties. When I launch it locally or use Enter-PSSession, the Command Line and Current Directory properties are set, but not when using New-PSSession or just Invoke-Command with ComputerName.
I'm using both Set-Location and setting the -WorkingDirectory, which are the 2 typical recommended approaches for setting the working directory, and Get-Location does display the expected (server's local) path (e.g. C:\inetpubLive\ScheduledJobs\1.2.3.4). I'm guessing that this is just a bug with PowerShell (I'm using V4 on workstation and server), or maybe there's something I'm missing?
UPDATE
It turns out that the working directory was a red herring (at least, I think it was). For some reason everything works fine if I called my executable from a command prompt.
So in my Invoke-Command (I replaced Start-Process with Invoke-Command), changing this:
& ""$hubSyncronizerExePath"" /database $database
to this:
& cmd /c ""$hubSyncronizerExePath"" /database $database
fixed the problem.
Thanks for all of the suggestions guys :)
Try looking at New-PSDrive and see if that helps
I guess you'll want something like
New-PSDrive -Name WorkingDir -PSProvider FileSystem -Root "\\RemoteServer\c$\inetpubLive\ScheduledJobs\1.2.3.4"
CD WorkingDir:
I assume you should be able to amend your script to include and put in the $version variable in to the path on the New-PSDrive command...
Not certain this will do what you need it to do, but it's the first thing that sprang to mind...
Alternatively, try amending your script as follows:
$hubSyncronizerExeDirectoryPath = "\\remoteserver\C$\inetpubLive\ScheduledJobs\$version\"
I'm my PS script I want to be able to run another script in another PS instance by doing the following:
$filepath = Resolve-Path "destruct.ps1"
start-process powershell.exe "$filepath"
destruct.ps1 is in the same folder as this script.
However when running this script in a location which includes spaces ("C:\My Scripts\") I will get the following error:
The term 'C:\My' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.
I know by using a '&' with the Invoke-Expression method solves this problem, how can I do the same but by using the start-process method?
try this:
start-process -FilePath powershell.exe -ArgumentList "-file `"$filepath`""
edit after comments:
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`""
side note:
$filepath is a [pathinfo] type and not a [string] type.
You can add escaped double quotes so that you pass a quoted argument:
"`"$filepath`""
I am answering here for a general scenario.
If you need to navigate to a folder for example C:\Program Files from the Powerhsell, the following command won't work as it has white space in between the path.
cd C:\Program Files
Instead embed the path with double quotes as like the below.
cd "C:\Program Files"
File name might contain spaces, so preserve spaces in full path:
Notepad++ exec command:
"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" "& \"$(FULL_CURRENT_PATH)\""
same from command prompt:
"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" "& \"C:\a_work\Systems\name with spaces.ps1\""
Just in case [string]$shipno (which is path & file name) comes in including spaces the following allows it to be passed to -FilePath successfully:
if ($shipno.contains(" ") -eq $true) {
$shipno = """" + $shipno + """"
}