Powershell hybrid here-string issue

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Olyrd
Posts: 25
Joined: 05 Feb 2016 07:36

Powershell hybrid here-string issue

#1 Post by Olyrd » 30 Mar 2016 23:51

Hello.

I have the following script:

Code: Select all

<# :
@echo off
setlocal
set "POWERSHELL_BAT_ARGS=%*"
if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%"
endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [char]10, $( Get-Content \"%~f0\" ) ) )"
goto :EOF
#>

$scriptPath = (Get-Item -Path ".\" -Verbose).FullName

$hosts = @"
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost
"@


$hosts| Out-File -Force $scriptPath\1.txt


When it outputs the file it does so without linebreaks in notepad (windows). In notepad++ it displays correctly.
What am I doing wrong?

Thank you

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Powershell hybrid here-string issue

#2 Post by foxidrive » 31 Mar 2016 01:29

If you open your hosts file in notepad, does it do the same thing?

Olyrd
Posts: 25
Joined: 05 Feb 2016 07:36

Re: Powershell hybrid here-string issue

#3 Post by Olyrd » 31 Mar 2016 01:39

No, I opened the hosts file and copied it, and opens correctly.

Using only the powershell code in Powershell (ISE) works correctly. I think the cmd hybrid is causing this.
When using the hybrid it outputs the entire hosts content in one line, no linebreaks.

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Powershell hybrid here-string issue

#4 Post by ShadowThief » 31 Mar 2016 03:10

Interesting; the Powershell code seems to be outputting \n linefeeds instead of \r\n linefeeds.

http://stackoverflow.com/a/20103499/4158862 is suggesting that you replace [char]10 with [Environment]::NewLine.

Olyrd
Posts: 25
Joined: 05 Feb 2016 07:36

Re: Powershell hybrid here-string issue

#5 Post by Olyrd » 31 Mar 2016 04:39

http://stackoverflow.com/a/20103499/4158862 is suggesting that you replace [char]10 with [Environment]::NewLine

It works! Thank you so much.

Complete code below:

Code: Select all

<# :
@echo off
setlocal
set "POWERSHELL_BAT_ARGS=%*"
if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%"
endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [char]10, $( Get-Content \"%~f0\" ) ) )"
goto :EOF
#>

$scriptPath = (Get-Item -Path ".\" -Verbose).FullName
$hostsFile = "$env:windir\System32\drivers\etc\hosts"
$nl = $([Environment]::NewLine)




$hostsContent = @"
# Copyright (c) 1993-2009 Microsoft Corp.
$nl
#
$nl
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
$nl
#
$nl
# This file contains the mappings of IP addresses to host names. Each
$nl
# entry should be kept on an individual line. The IP address should
$nl
# be placed in the first column followed by the corresponding host name.
$nl
# The IP address and the host name should be separated by at least one
$nl
# space.
$nl
#
$nl
# Additionally, comments (such as these) may be inserted on individual
$nl
# lines or following the machine name denoted by a '#' symbol.
$nl
#
$nl
# For example:
$nl
#
$nl
#      102.54.94.97     rhino.acme.com          # source server
$nl
#       38.25.63.10     x.acme.com              # x client host
$nl
$nl
# localhost name resolution is handled within DNS itself.
$nl
#   127.0.0.1       localhost
$nl
#   ::1             localhost
$nl
"@




$hostsContent| Out-File -Force $hostsFile



One more thing:
Could you guy help me understand why it gives me access denied error when executing the script as admin? I used right-click menu, Run As Administrator. Doesn't work.

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Powershell hybrid here-string issue

#6 Post by ShadowThief » 31 Mar 2016 10:14

That's a bit much. I meant that the correct code would be

Code: Select all

<# :
@echo off
setlocal
set "POWERSHELL_BAT_ARGS=%*"
if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%"
endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [Environment]::NewLine, $( Get-Content \"%~f0\" ) ) )"
goto :EOF
#>

$scriptPath = (Get-Item -Path ".\" -Verbose).FullName

$hosts = @"
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost
"@


$hosts| Out-File -Force $scriptPath\1.txt

Olyrd
Posts: 25
Joined: 05 Feb 2016 07:36

Re: Powershell hybrid here-string issue

#7 Post by Olyrd » 31 Mar 2016 23:26

Thanks, I didn't knew that could be solved like that.
I'm having trouble now overwriting the hosts file. I run the script with Run as admin but it still displays the error "Access denied". Any ideas?

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Powershell hybrid here-string issue

#8 Post by ShadowThief » 31 Mar 2016 23:44

I can't replicate your problem; right-clicking on the script and selecting "Run as administrator" works exactly as you'd expect it to for me.

Olyrd
Posts: 25
Joined: 05 Feb 2016 07:36

Re: Powershell hybrid here-string issue

#9 Post by Olyrd » 01 Apr 2016 00:03

I'm not implying anything here but you did modify this line

Code: Select all

$hosts| Out-File -Force $scriptPath\1.txt

to

Code: Select all

$hosts| Out-File -Force C:\Windows\System32\drivers\etc\hosts

right?

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Powershell hybrid here-string issue

#10 Post by ShadowThief » 01 Apr 2016 00:16

Naturally. Full code:

Code: Select all

<# :
@echo off
setlocal
set "POWERSHELL_BAT_ARGS=%*"
if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%"
endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [Environment]::NewLine, $( Get-Content \"%~f0\" ) ) )"
goto :EOF
#>

$scriptPath = (Get-Item -Path ".\" -Verbose).FullName
$hostsFile = "$env:windir\System32\drivers\etc\hosts"

$hostsContent = @"
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost

127.0.0.1       localhost
"@


$hostsContent| Out-File -Force $hostsFile

Post Reply