PowerShell scriptBlock wraps the script when trying to write scriptblock to file - powershell

I am trying to create a PowerShell script by another PowerShell script. I have something like:
>
$scriptBlock = {
write-host "this is the body of the script that I want to add to another PS script"
if($true){
write-host "so that I can execute this automatically created script somewhere "
}
}
$scriptBlock | Out-String -Width 4096 | Out-File "c:\test.ps1"
AtRunUnattended.exe "$($Dict.Get_Item("MASTER_DIRECTORY_PATH"))\MEDIA_FILE\" /S /noreboot /L logfile="%TEMP%\AT $($Dict.Get_Item("PRODUCT_NAME")) V8.4.log" altsource="C:\temp\baf\mediafile"
However, when I have some long single-line scripts like the one shown above, it gets automatically wrapped so the out-put .ps1 file would not work as if I had invoked the script directly from the parent script.
So in the .ps1 file that the parent .ps1 script created, the code then looks like this:
ElseIf($str.StartsWith("DRIVER_DATE=")){$str = "DRIVER_DATE=$(Get-Date
-f MM-dd-yyyy))"}
which will not run properly if it is run.
So does anybody know how to text-format scriptblocks so that they can be properly written to another child script file for further execution?
I did some research and I think that it might have something to do with PS's internal text buffer width or something. I tried other out-file methods as well like [System.IO.StreamWriter], however all of them look the same--wrapped and limited to a certain width per line.
Please help me, thank you!
The entire purpose of this thing is to generate some scripts automatically and remotely execute these created scripts on other machines.

Use the -Width parameter with the Out-File cmdlet as follows:
Out-File -FilePath "c:\test.ps1" -Width 4096

the variable will not be expanded in single quote. May be you need a sample like this:
$scripts=#'
$date=get-date
"Hello,now is $date"
'#
$scripts | Out-File second.ps1
./second.ps1
Output is:
Hello,now is 09/23/2013 23:41:18

Related

PowerShell Start-Job not creating or amending files

I am new to PowerShell and this is the first time I am attempting to use a job. I am running into an issue where I have a part of a script that looks for a file, creates it if it doesn't exist and then amends the file, and when I run the script (not as a job) it executes correctly, but when I put it in a job, it doesn't amend the file.
A much simplified example of what I have is this:
Start-job -Name HostCheck -ScriptBlock {
ForEach ($Host in (Get-Content -Path .\HostFile.txt) {
Add-Content .\somefile.txt "`nWrite something on a new line for $Host"
} | Out-Null
}
# Removes job once it is finished
Get-Job -Name HostCheck | Wait-Job | Remove-Job
Now I have tried adding | Receive-Job after the | Out-Null, but that didn't seem to change anything.
I've seen people write the entire script-block to a variable and just use the variable instead, so I am curious if that is a requirement (but I wouldn't think so).
Also, this might matter, I open the script with a .bat file that escalates the PowerShell console to admin as well as setting the execution policy of the process to Bypass. Now it seems that everything that runs in that console session or is kicked off by that console session (several scripts get ran, this is just part of one of them) seems to inherit those settings, but being new with jobs, I don't know if it would also inherit those settings, or how I would force it to (if not).
I discovered the problem:
-Your current working directory is lost when starting a job so my relative path .\somefile.txt would default to C:\Users\[Username]\Documents instead of the location where the .\somefile.txt resides.
I can get around this by using an absolute path, or I think there is a way to pass arguments to a job, but if anyone knows a better way to do this, please feel free to comment.
Here's a workaround, cd to the current dir of the caller.
start-job { cd $using:pwd; pwd } | Receive-Job -wait -auto

Powershell write output of a program to a console live and pipe to a file

I am running a fairly complex python script from a powershell script. I would like to both display the stdout and stderr streams of the .python script in the console in real time (ie as the .py script writes to them) and also write them to a file.
My current solution looks like this:
Do-PreliminaryStuff
log = & ".\myPyScript.py" -myArgument "\this\that\thingy.txt" 2>&1 $log
Write-Output $log
$log | Out-File "$logDir\pyScriptLog.log"
Do-RestOfScript
This has the problem that the text is only printed out after the .py script has finished, making it much harder to watch the progress of the .py script.
Is there a way to somehow ..sample.. the pipeline as object go through it?
You are probably looking for the Tee-Object cmdlet.
Use Tee-Object - it splits the pipeline into a filestream before continuing:
& ".\myPyScript.py" -myArgument "\this\that\thingy.txt" 2>&1 |Tee-Object -FilePath $log

Powershell outputting an executable into a text file

I'm trying to write a Powershell script for work that will take the output of w32tm.exe \monitor and output everything into a text file. I'm trying the following code, however something is wrong since I'm able to create the text file, but nothing is being written in it:
#Take output of w32tm.exe and output into a plain text file
$file = "C:\Documents and Settings\a411882\My Documents\Scripts\timeScript.txt"
$executable = "w32tm.exe /monitor"
invoke-expression $executable | out-file -filepath $file
What am I doing wrong here? I'm new to Powershell so any advice would be greatly appreciated!
EDIT:
I can get all of the data to be displayed on the console when I run this, however I want the data to be written on the text file.
EDIT 2:
I managed to get everything to finally output. I wanted to try avoiding using the > operator to write out to the text file in hopes of learning a little more on the out-file cmdlet however doing a simple invoke-expression $executable > $file managed to get the job done. I still don't understand why the cmdlet wouldn't work properly.
Perhaps Invoke-Expression isn't properly sending output to stdout? I wouldn't expect that, but stranger things have happened. Try running w32tm.exe on its own:
$file = "C:\Documents and Settings\a411882\My Documents\Scripts\timeScript.txt"
w32tm.exe /monitor | Out-File -FilePath $file
You could use Start-Process which allows you to redirect also the error output:
Start-Process w32tm.exe -ArgumentList "/monitor" -Wait -RedirectStandardOutput "output.txt" -RedirectStandardError "error.txt"

Dot sourcing a PowerShell script not ending with .ps1

From a PowerShell program, I can "dot source" another PowerShell program. i.e I can execute it as if it were written inside the first one.
Example:
Write-Host 'before'
. MyOtherProgram.ps1
Write-Host 'after'
MyOtherProgram in 'included' inside the main program, exactly as if its content had been copy/pasted.
The problem is: I can only dot source a filename finishing with .ps1
I can't with MyOtherProgram.lib or MyOtherProgram.whatever
Anyone have a method to dot source a PowerShell script not ending with .ps1 ?
Another way would be using Invoke-Expression:
$code = Get-Content ./MyOtherProgram.lib | Out-String
Invoke-Expression $code
I'm not aware if this is compiled into PowerShell or if it's configurable but one way to do it is just have your script temporarily rename it, import it and then rename it back.
Rename-Item C:\Path\MyScript.whatever C:\Path\MyScript.ps1
. C:\Path\MyScript.ps1
Rename-Item C:\Path\MyScript.ps1 C:\Path\MyScript.whatever

Trying to output powershell "Add-Computer" command to text file

I'm running a .PS1 script as part of a larger script to get computers to join our domain semi-automatically. The .PS1 is created from variables and ends up looking like this:
add-computer -DomainName ourdomain.com - OUPath "OU=Computers,OU=Somewhere,DC=OURDOMAIN,DC=COM" -Cred OD\syswdg
While this works fine, I would like to be able to output the restult of this to a text file so that I can check if this has worked sccessfully or not before proceeding to do other stuff in the script. Is there any way to get the results of this output to a file? I've tried using the Out-File Cmdlet, the Tee-Object Cmdlet and tried running the joindomain.PS1 from another PS1 like joindomain.ps1 > outputfile.txt and while they all produce a file, it is always empty. Any help appreciated.
By default, there is no output when the cmdlet is successful. Use -Passthru and -Verbose if you want to see the output of this cmdlet.