Special character in string path causes an error. Powershell - powershell

I have a powershell script that gets the Java environment variable within the PATH which could be as follows:
$java = (Get-Command java | Select-Object -ExpandProperty Source).toString()
Outputs: $java = C:\Program Files (x86)\Java\jdk1.8.0\bin\java.exe
Then, I set the JAVA_HOME env variable by removing the \bin\java.exe path
$env:JAVA_HOME = "$java" -replace "\\bin\\java\.exe",""
And call a .bat script.
The main problem is that I get an error due to the parenthesis in (x86) within the .bat script:
\Java\jdk1.8.0 was unexpected at this time.
If I change the java path to Program Files (without any parenthesis) everything works fine. So I have been trying to escape special characters in the -replace method but nothing seems to be working.
$env:JAVA_HOME = "$java" -replace "\\bin\\java\.exe","" -replace [regex]::Escape(')'), [regex]::Escape(')') -replace [regex]::Escape('('),[regex]::Escape('(')
Any ideas?

Related

How do I pass the Gitlab {CI_COMMIT_SHORT_SHA} variable to powershell script

I have created a script section in Gitlab-CI.yaml file. The format is given below.
script:
- powershell -File script.ps1 folderpath="$env:${CI_PROJECT_DIR}" CommitID="$env:${CI_COMMIT_SHORT_SHA}"
and these variables are calling in my PowerShell script as follows. The script is given below.
$Files = Get-ChildItem $folderpath
foreach($eachFile in $Files)
{
if($eachFile.Name.Contains("myapp"))
{
Rename-Item -Path $eachFile.FullName -NewName "myapp-$CommitID.zip" -Force
}
}
This script is using for changing the name of a zip file. After execting this through gitlab I am getting error like this.
Variable reference is not valid. ':' was not followed by a valid variable name
character. Consider using ${} to delimit the name.
Is it the right format to pass the GitLab env variable to PowerShell script? Can you please suggest some inputs on this?
Assuming that ${CI_PROJECT_DIR} is the value of GitLab's CI_PROJECT_DIR (environment) variable, you can use it as-is in your command line - no need for the $env: indirection, which (a) requires the name of an environment variable and (b) wouldn't work anyway with PowerShell's -File CLI parameter.
Assuming your target script uses regular PowerShell parameter declarations (e.g., param($FolderPath, $CommitId), case doesn't matter), you must pass the values using
-<param> <value> or -<param>:<value> syntax.
To put it all together:
script:
- powershell -File script.ps1 -FolderPath "${CI_PROJECT_DIR}" -CommitID="${CI_COMMIT_SHORT_SHA}"
The alternative is not to use parameters at all, and instead directly access the environment variables from inside your script, using PowerShell's $env:<var_name> notation:
$Files = Get-ChildItem $env:CI_PROJECT_DIR
foreach($eachFile in $Files)
{
if($eachFile.Name.Contains("myapp"))
{
Rename-Item $eachFile.FullName -NewName "myapp-$env:CI_COMMIT_SHORT_SHA.zip" -Force
}
}

Get-Content - cannot find path error in windows command prompt

I was trying to execute powershell script from Cmd.
C:\powershell C:\Powershell_Scripts\CheckWebSiteExists.ps1
Error : Get-Content : Cannot find path '\\XXXX\China-team\Release
Package\CustomerDB_file\CustomerDB.txt' because it does not
exist.
Powershell script :
$test = (Get-Content "\\XXXX\China-team\Release Package\\CustomerDB_file\CustomerDB.txt") -split ','
this was running fine in powershell but not in cmd. I have mapped that share path and tried executing, but no luck.
Try This..
powershell -command "$test = (Get-Content "\\XXXX\China-team\Release Package\\CustomerDB_file\CustomerDB.txt") -split ','"
It appears that PowerShell cannot find the filename you have specified. Take a step back and verify that the file is there.
Test-Path '\\XXXX\China-team\Release Package\\CustomerDB_file\CustomerDB.txt'
If that does not return True, try removing the escaped backslash.
Test-Path '\\XXXX\China-team\Release Package\CustomerDB_file\CustomerDB.txt'
If Test-Path cannot return True, then the file cannot be found. There is no point in using Get-Content until the file can be found.

Script to replace line that contains text

I found another discussion on this, where there were numerous different options available but most of them didn't seem to work for myself or the original poster. I did however find an example that is confirmed working, however I am struggling with getting it to work and hoping for help.
I need to find a line that begins with "ServerName=" and replace this with my own line. I have used the example that was found and modified it, but I am getting errors when using it.
PowerShell Command:
powershell -Command "(Get-Content 'KFGame\Config\PCServer-KFGame.ini') | Foreach-Object {$_ -replace '^ServerName.$', ('ServerName=Network BUF 12345 Normal')} | Set-Content 'KFGame\Config\PCServer-KFGame.ini'"
Error Message:
) was unexpected at this time
If you want to run complex PowerShell statements from CMD you need to put them in quotes so that CMD just sees a string and doesn't try to handle special characters (like pipes):
powershell -Command "(Get-Content 'C:\Host400.txt') | Foreach-Object {$_ -replace '^workstationID.*$', (""WorkstationID=$computerName""} | Set-Content 'C:\Host400.txt'"
Note that you need to either escape or replace double quotes within the command string.
A better approach is to put the PowerShell statement(s) into a .ps1 script and run that via the -File parameter:
powershell -File "C:\path\to\your.ps1"

How to find whether a non-command file is available in the system path?

I want to test whether a certain file is in the system PATH. in cmd, I can do it using where.exe my.dll.
How do I do it in PowerShell?
This answer suggests Get-Command, which works only for executables - I want to find DLLs as well.
gci ($env:Path).split(';') -Filter *.dll
You could search the path for it as follows:
$ENV:Path -split ';' | % { if ( test-path "$_\my.dll") { write-host $_ } }
The PATH variable is semi-colon separated, so you can split the string using ; as the delimiter, then loop over each location with the file you're seeking appended. If a location is printed, your file will be on the path.

Powershell misunderstand quotation marks in a file name

Yes these files do have quotation marks in the file name.!!
I am trying to run a bat file using a powershell script. Powershell script iterate through a folder and extract files. It then pass these file names to the batch script which calls an exe to process them.
This is what the powershell script looks like,
$path = "\\RemoteMachine\Japanese\files"
$filter = "*.msg"
$count = 0
Write-Host "Parsing started...";
get-childitem -recurse -path $path -filter $filter| % {
$count++;
& "C:\Users\uname\myfolder\runCommads.bat" "$($_.FullName)" "C:\Users\uname\myfolder\output\$count.txt"
}
The input files were written using a different language. Some files' names consist of quotation marks. When PS script runs runCommand.bat, spaces that contain in the file name are misinterpreted. A Word that succeeds a space is considered as a name of a different file.
But if I run the batch file without PS script, for just one file that contains quotation marks in the file name, the expected out is given.
Could someone help me with a solution for this problem?
Thank you
This seems to be a problem of the batch file not of the powershell script.
Normally the batch parser splits the parameters at spaces.
It can be suppressed by using quotes, but if your filename itself contains quotes it will again fail.
But you could double all quotes in the filename (inside the powershell script),
then it should be possible to get the correct filenames in the batch file.
Inside the batch you need to remove the doubled quotes, but that seems to be easy.
set "filename=%~1"
setlocal EnableDelayedExpansion
set "filename=!filename:""="!"
But I suppose, that the most batch commands will fail with such filenames.