powershell create ini file remotely - powershell

I am trying to create a script to create an ini file via powershell to disable windows UAC.
$functionText = #"`[Options`]
UpdateKey=04/28/2015 12:50:27 AM
WINDOW_LEFT=258
WINDOW_TOP=149
WINDOW_WIDTH=666
WINDOW_HEIGHT=519
WINDOW_MAX=0
BackupDir=C:\Windows\System32
UpdateCheck=1
Language=1033
(App)Sun Java=False
NewVersion=5.05.5176
SkipUAC=1
FinderInclude1=PATH|C:\|*.*|RECURSE
FinderInclude2=PATH|D:\|*.*|RECURSE
FinderIncludeStates=1|1
I see SkipUAC=1
ShowCleanWarning=False
ShowFirefoxCleanWarning=False
WipeFreeSpaceDrives=C:\
RunICS=0
CookiesToSave=*.piriform.com|google.com
"#
New-Item c:\Program Files\Ccleaner\Ccleaner.ini -type file -force -value $functionText
I keep getting Unrecognized token in source text.
At C:\PROGRA~3\BEANYW~1\Scripts\2480_C~1\~SC52F~1.PS1:1 char:17
+ $functionText = <<<< #"[Options]
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnrecognizedToken
I tried adding the escape character around options to see if that would do it - I think the issue is around the word [options]

If you want to use a here-string, put the #" on a line by itself.
$functionText = #"
[Options]
UpdateKey=04/28/2015 12:50:27 AM
WINDOW_LEFT=258
WINDOW_TOP=149
WINDOW_WIDTH=666
WINDOW_HEIGHT=519
WINDOW_MAX=0
BackupDir=C:\Windows\System32
UpdateCheck=1
Language=1033
(App)Sun Java=False
NewVersion=5.05.5176
SkipUAC=1
FinderInclude1=PATH|C:\|*.*|RECURSE
FinderInclude2=PATH|D:\|*.*|RECURSE
FinderIncludeStates=1|1
I see SkipUAC=1
ShowCleanWarning=False
ShowFirefoxCleanWarning=False
WipeFreeSpaceDrives=C:\
RunICS=0
CookiesToSave=*.piriform.com|google.com
"#
New-Item "C:\Program Files\Ccleaner\Ccleaner.ini" -type file -force -value $functionText
The advantage of a here-string is that you don't have to escape anything inside the string. So if there were single or double quotes it wouldn't matter. As long as the literal string '"#' doesn't exist, on a line by itself, inside the ini file code you're safe.
Read more about here-strings.
Also, as shown in the sample above, you need to put quotes around the file path.

Related

How to assign and reference environment variables containing square brackets in Powershell

When the PSDrive is not specified, the following works:
${[foo]}="bar"
echo ${[foo]}
But the following does not work
$env:${[foo]}="bar"
At line:1 char:1
+ $env:${[foo]}="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to delimit the name.
At line:1 char:6
+ $env:${[foo]}="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '${[foo]}="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
${env:[foo]}="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ ${env:[foo]}="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound
The following works, though I am curious if there's short hand syntax for it:
Set-Item -LiteralPath env:${[foo]} -Value "bar"
Get-Item -LiteralPath env:${[foo]} | % {$_.Value}
However the following does not work:
Set-Item -LiteralPath env:${[foo]2} -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:${[foo]2} -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
${<drive>:<name>}
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in ${env:[foo]} - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to ${env:[foo]}, the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., ${env:NoSuchVarExistsYet} = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
${env:``[foo``]} = 'bar'
# Get its value.
${env:``[foo``]}
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see GitHub issue #9225.
That double `-escaping is needed is an added quirk - see GitHub issue #7999.
Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:${[foo]}="bar"
Since your variable reference isn't {...}-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, { and } all violate that rule.
{...}-enclosing the entire path - ${env:[foo]} - solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:${[foo]} -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:${[foo]}": the reference to a (regular) variable named ${[foo]} is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
${[foo]} = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:${[foo]} bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:${[foo]} and
Set-Item -LiteralPath env:${[foo]2} -Value "bar".

Function prompts value for Add-Content and treats .txt file as directory

I am writing a PowerShell script for creating error status files. The info I need is defined in a global variable ($info) and is returning the correct string I need it to. The type is System.String.
function Add-Fail
{
$date = Get-Date -f "yyyy-MM-dd"
Add-Content \\Path\To\FailMonitor\${date}.txt $info
}
I have also tried passing the variable like this:
function Add-Fail ($info)
{
$date = Get-Date -f "yyyy-MM-dd"
Add-Content \\Path\To\FailMonitor\${date}.txt $info
}
and calling it like this where info is a string:
Add-Fail($info)
and this
Add-Fail -info $info
For both of these cases, I get the same output which is asking for a value. If I input values, it keeps prompting me for the next one in an infinite array. If I don't input one and just hit enter, it gives me an error that has no information, and even refers to my Add-Content line on the complete wrong line number.
Output (Edited out username):
cmdlet Add-Content at command pipeline position 1
Supply values for the following parameters:
Value[0]: 1
Value[1]: 2
Value[2]:
Add-Content : The filename, directory name, or volume label syntax is incorrect.
At C:\Users\********\Documents\Workspace\Error_Monitor.ps1:40 char:5
+ Add-Content \\nserver\scsi\HPQ\FailMonitor\$date\
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (\\nserver\scsi\...tor\2016-10-18\:String) [Add-Content], IOException
+ FullyQualifiedErrorId : GetContentWriterIOError,Microsoft.PowerShell.Commands.AddContentCommand
As you can see, it refers to my date as a directory. For reference, my Add-Content expression is on line 45, char 5. It sees my .txt file as a directory and treats it as such. The text file is not a directory at all. It isn't a variable problem either as I have cleared the variables. I have also tried no brackets around the date, but that didn't work either.
Why is PowerShell behaving like this? What am I missing?

powershell CategoryInfo NotSpecified and newlines

I have an app that prints text to stderr, so to save to a file, I do this:
.\NGPQUERY.exe -spoof -stages -diag 2> c:\foo.txt
None of the text is special characters, other than crlf at the end of lines.
In DOS, the output is fine.
In powershell the output is almost fine.
The first line of text is this:
RTE Routings for BRI to LED - 00:
I get this error message at the top of the output:
NGPQUERY.exe : RTE Routings for BRI to LED - 00:
At line:1 char:15
+ .\ngpquery.exe <<<< -spoof -stages -diag 2> e:\foo
+ CategoryInfo : NotSpecified: (RTE Routings for BRI to LED - 00: :String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Then throughout the output, line feeds are added at seemingly random locations. So my question is how do I get rid of the error and the random line feeds.
Also powershell outputs file that is twice as large as the dos file, I'm guessing its unicode. So I would like to know the best way get an ansi output too.
If you only need STDERR, this should be enough:
$oPsi = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$oPsi.FileName = "NGPQUERY.exe"
$cArgs = #("-spoof", "-stages", "-diag")
$oPsi.Arguments = $cArgs
$oPsi.CreateNoWindow = $true
$oPsi.UseShellExecute = $false
$oPsi.RedirectStandardError = $true
$oProcess = New-Object -TypeName System.Diagnostics.Process
$oProcess.StartInfo = $oPsi
[Void]$oProcess.Start()
$sStdErr = $oProcess.StandardError.ReadToEnd()
[Void]$oProcess.WaitForExit()
$sStdErr | Out-File -Encoding "ASCII" -FilePath "C:\foo.txt"
This is an old question, but I got here because I had a similar problem and found the easiest solution to be to call cmd.exe and surround the command in quotes, to prevent Powershell from interpreting it. So in the above case that would be:
cmd.exe /c ".\NGPQUERY.exe -spoof -stages -diag 2> c:\foo.txt"

powershell is missing the terminator: "

I have the following script code
#[string]$password = $( Read-Host "Input password, please" )
param (
[string]$ReleaseFile = $(throw "-ReleaseFile is required"),
[string]$Destination = $(throw "-Destination is required")
)
function unzipRelease($src, $dst)
{
$shell = new-object -com shell.application
$zip = $shell.NameSpace($src)
foreach($item in $zip.items())
{
$shell.Namespace($dst).copyhere($item)
}
}
# .\deployrelease.ps1 -ReleaseFile ".\deploy.zip" -Destination "."
unzipRelease –Src '$ReleaseFile' -Dst '$Destination'
I run the script with: .\deployrelease.ps1 -ReleaseFile ".\deploy.zip" -Destination "."
But I keep getting this:
PS C:\Users\Administrator\Documents\Tools> .\deployrelease.ps1 -ReleaseFile ".\deploy.zip" -Destination
The string starting:
At C:\Users\Administrator\Documents\Tools\deployrelease.ps1:19 char:16
+ unzipRelease â? <<<< "Src '$ReleaseFile' -Dst '$Destination'
is missing the terminator: ".
At C:\Users\Administrator\Documents\Tools\deployrelease.ps1:19 char:55
+ unzipRelease â?"Src '$ReleaseFile' -Dst '$Destination' <<<<
+ CategoryInfo : ParserError: (Src `'$ReleaseF...'$Destination`':String) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
I couldn't find the fix as I do not see any problem.
Any help?
Look closely at the two dashes in
unzipRelease –Src '$ReleaseFile' -Dst '$Destination'
This first one is not a normal dash but an en-dash (– in HTML). Replace that with the dash found before Dst.
In my specific case of the same issue, it was caused by not having the Powershell script saved with an encoding of Windows-1252 or UFT-8 WITH BOM.
This can also occur when the path ends in a '' followed by the closing quotation mark.
e.g. The following line is passed as one of the arguments and this is not right:
"c:\users\abc\"
instead pass that argument as shown below so that the last backslash is escaped instead of escaping the quotation mark.
"c:\users\abc\\"
In your script, why are you using single quotes around the variables? These will not be expanded. Use double quotes for variable expansion or just the variable names themselves.
unzipRelease –Src '$ReleaseFile' -Dst '$Destination'
to
unzipRelease –Src "$ReleaseFile" -Dst "$Destination"
This error will also occur if you call .ps1 file from a .bat file and file path has spaces.
The fix is to make sure there are no spaces in the path of .ps1 file.
You can spot the error when using # prefix/suffix with multiline string while you actually have the ending suffix "#.
My script looked like that:
Add-Type #"
public class SomeClass {
...
}"#
and I still got the: The string is missing the terminator: "#.
Message was misleading because all I needed to do was to put "# into new line without any leading space:
Add-Type #"
public class SomeClass {
...
}
"#
my folder contained ' symbol. After I removed it, the issue resolved.
if you're using RHEL, try replacing " with ' - this fixed the error for me
cheers

Userprofile messed up

I have a little problem here with my user profile path for the use with powershell.
I have set my profile.ps1 to this:
$Shell = Host.UI.RawUI
$Shell.WindowTitle="PowerShell obeys me!"
$Shell.BackgroundColor="White"
$Shell.ForegroundColor="Blue"
$size = $Shell.WindowSize
$size.width=120
$size.height=50
$Shell.WindowSize = $size
$size = $Shell.BufferSize
$size.width=120
$size.height=5000
$Shell.BufferSize = $size
but everytime i execute run poweshell, it shows some erors like this one:
Property 'WindowTitle' cannot be found on this object; make sure it exists and is settable.
At D:\data\d7bighs\Documents\WindowsPowerShell\profile.ps1:5 char:8
+ $Shell. <<<< WindowTitle="PowerShell obeys me!"
+ CategoryInfo : InvalidOperation: (WindowTitle:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
now is i check my profile it tells me this:
$profile
d:\data\myusername\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
but if i check this through windows explorer it tells me this:
d:\User\myusername\Documents\WindowsPowerShell\profile.ps1
Im confused here because within explorer tells me d:\Useres but PS shows it as d:\data...
How can i change this or force PS to look after d:\users instead of d:\data?
a tiny error: $Shell = $Host.UI.RawUI, and you may need to create the profile first by
New-Item -Path $PROFILE -Type file
then edit it by
notepad $PROFILE