I'm installing a file through powershell silently, but would like to give feedback on the progress of the installation. I can't seem to find this information anywhere. This is the code I have for running the exe:
$exe = "wls1033_oepe111150_win32.exe"
$xmlLocation = Resolve-Path "silent_install.xml"
$xmlLocation = "-silent_xml=" + $xmlLocation
$installLogLoc = Resolve-Path "wls_install.log"
$installLogLoc = "-log=" + $installLogLoc
$AllArgs = #('-mode=silent', $xmlLocation, $installLogLoc)
$filePath = Resolve-Path $exe
$p = New-Object System.Diagnostics.Process
$p.StartInfo.Filename = $filePath
$p.StartInfo.Arguments = $AllArgs
$p.Start();
$p.WaitForExit();
Is there even a way to do this? I do get a progress meter for the extraction process in an alternate command window that installs the exe, but other than that it sits for there about 10 minutes with no sort of indication.
Edit: So seeing as this isn't possible, is there a way to do an asynchronous pipeline call while running the exe?
Thanks
Please correct me if I'm wrong, but I'm 99% sure that this is NOT possible. Your exe file is seperate process and not a PowerShell script. It will not be able to pass status messages to your PowerShell sessions. The only possibility would be to detect the setups log-file, tail it and update a progressbar in PowerShell based on keywords from the log. This is however a big task and something you need to customize for each setup file.
I would try to look into your exe file and see if it has a "basic ui" (or a similar type) mode that you can use instead of the silent option. A last alternative would be to repackage the setup with such an option(making installation automated with only progressbar). This solution would still only show the progressbar in a separate window and not in PowerShell itself.
Related
When I am running commands or installing software remotely using PowerShell - Invoke-Command etc I would like sometimes to be able to show a message on the remote screen so the user knows something is happening, or when work done etc.
I would like to if possible make this message look as professional as possible, e.g. better than just a standard winform message box if it can be done? perhaps more the style of the Windows 10 ones with coloured background and use of image if possible.
Spent a while googling but most seem to relate to using obsolete methods such as net-send or using msg.exe.
Thanks
https://michlstechblog.info/blog/powershell-show-a-messagebox/
So the issue really isnt creating the messagebox itself, its having it show on the users session.
So when you run a command against a system, youre using your creds to run the command therefore it wont show in the users session. You can get around this by running it in the users context using a task scheduler. I have a script that does all this for you but, id hate to recreate the wheel and will have to wait till monday (when im at work) to post it here.
It accepts user input in your sessions that outputs it to a vbs, which then copies it over the message to the users machine, and a task schedule is set to run immediately for the user thats logged in.
edit: The script is this without the task scheduler. I just invoke gwmi win32_computersystem | Select -ExpandProperty username to get the current user logged in and add it to the task.
#Prompt for messge
$strMSG = Read-Host -Prompt "Enter message"
#deleting vbs if it exists
del C:\brief\test.vbs
#creating vbs from scratch so it doesnt override
New-Item C:\brief\test.vbs
#Appending each the values to a seperate line
Add-Content C:\brief\test.vbs 'Set objShell = Wscript.CreateObject("WScript.Shell")'
Add-Content C:\brief\test.vbs "strText = `"$strMSG`""
Add-Content C:\brief\test.vbs 'intButton = objShell.Popup(strText,0,"Computer Support",48)'
#calling on the script
& cscript C:\brief\test.vbs
Found a great solution here which appears on quick testing to work well for displaying a toast notification on a remote machine
https://smsagent.blog/2019/06/11/just-for-fun-send-a-remote-toast-notification/
I have a command which runs a program in silent mode, it uses an XML file for the data repository and a word template to create multiple word documents based on a filter xml file.
The command I use is:
"P:\ath to\executable" -Username:Admin -Password:Pa55w0rd -Datadefinition:"C:\Data.xml" -Datafilter:"C:\Filter.xml" -wordtemplate:"C:\Batch\Paul1.dotx" -Targetdocument:="C:\Batch\Paul1.pdf" -filetype:PDF -Log:"C:\Logs\error.log" -Usage:DOCGENSILENT
I need to run this as a PowerShell script which I have mostly managed:
set-executionpolicy unrestricted
$datadefinition = Get-Content "C:\Data file.xml"
$datafilter = Get-Content "C:\Filter for data file.xml"
$wordTemplate = Get-Content "C:\"C:\Template\Paul1.dotx"
$targetFolder = Get-Content "C:\"C:\Paul\Paul.pdf"
Stop-Job = "Executable path" -Username:Admin -Password:Pa55w0rd -Datadefinition:%dataDefinition% -Datafilter:%dataFilter% -wordtemplate:%wordTemplate% -Targetdocument:%targetFolder% -filetype:docx -Log:%logPath% -Usage:DOCGENSILENT
Stop-Job 1
set-executionpolicy restricted
Write-Host -NoNewLine "Press any key to continue..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
My issue is that the script starts the executable but then doesnt pass the Variables, can anyone guide me in the right direction to fix this?
Getting this working depends on the behavior of your executable. Some things I noticed:
Shouldn't this:
$wordTemplate = Get-Content "C:\"C:\Template\Paul1.dotx"
be this:
$wordTemplate = "C:\Template\Paul1.dotx"
Are you sure you need Get-Content? (Aside from that, the path and quoting in your sample are not correct.)
Shouldn't this:
$targetFolder = Get-Content "C:\"C:\Paul\Paul.pdf"
be this:
$targetDocument = "C:\Paul\Paul.pdf"
I doubt Get-Content is correct here, since presumably your output file doesn't exist yet? I also renamed the variable so it makes more sense in your command.
In fact, are you sure you need Get-Content for any of those? Aren't you specifying filenames, not the content of the files?
In PowerShell, variables are prefixed with $ rather than being surrounded by %.
Using Set-ExecutionPolicy within a script to enable scripts to run is pointless, because the script is already running. (That is, if execution policy prevented script execution, PowerShell wouldn't let you run the script in the first place.)
If my guesses regarding your variables are correct, I think your script should look something like this (note also that I specified a $logFile variable, which I didn't see in your script):
$datadefinition = "C:\Users\Administrator\data\Sample Model_146_object type(s).xml"
$datafilter = "C:\Users\Administrator\data\Sample Model_146_object type(s).xml"
$wordtemplate = "C:\Users\Administrator\Templates\Base object.docx"
$targetdocument = "C:\Users\Administrator\Result\sample test15"
$logfile = "C:\Users\Administrator\Logs\C4W Error.log"
& "C:\Program Files (x86)\Communicator4Word.exe" -Username:Admin -Password: -Datadefinition:$datadefinition -Datafilter:$datafilter -wordtemplate:$wordtemplate -Targetdocument:$targetdocument -filetype:docx -Log:$logfile -Usage:DOCGENSILENT
I don't know the behavior of Communicator4Word.exe when you use -Password: with no password after it. (Is that a syntax error, or should you just omit -Password: altogether?)
I'm trying to create a .exe file that will run a powershell script that I have to install various components of an application. I'm working on step 1 of 4 to get this entire application installed and want to get it into one package. Things are not going well with it. I am using Ps1 to Exe by f2ko. There is no documentation that I can find on the software, but it does what I want it to. The issue is in the packaged files and how it is run. I am running into a couple issues. The primary issue seems to be with Start-Process, When the exe is running I get an error that states
Start-Process : This command cannot be run completely because the system cannot find all the information required.
At C:\Users\adminjp\AppData\Local\Temp\2605.tml\2606.tmp\2607.ps1:9 char:16
The remainder of the error is obscured by a status bar for the installer. The status bar runs, but the process does not. I initially had an issue with ExecutionPolicy but that is rectified by manually changing the value in order to run the script. I have been having multiple issues getting this script to run and am running out of articles online that I haven't read. Here is my powershell script:
Set-ExecutionPolicy -Force remotesigned
$NETfile = "env:p2eincfilepath\1 - NDP471-KB4033342-x86-x64-AllOS-ENU.exe"
$NETargs = "/q"
$SQLfile = "env:p2eincfilepath\setup.exe"
$SQLargs = "/ConfigurationFile=`".\ConfigurationFile_SQLExpress.ini`""
function Show-Progress ($file, $arguments, $component){
$process = Start-Process $file $arguments -PassThru
for($i = 0; $i -le 100; $i = ($i + 1) % 100)
{
Write-Progress -Activity "Installer" -PercentComplete $i -Status "Installing $component"
Start-Sleep -Milliseconds 100
if ($process.HasExited) {
Write-Progress -Activity "Installer" -Completed
break
}
}
}
Show-Progress $NETfile $NETargs ".NET 4.7.2"
Show-Progress $SQLfile $SQLargs "SQL Express"
The program that converts this script to an exe is what sets the extraction location and, to the best of my knowledge, I have no way to set that. Attached is a screenshot of their explanation of how to reference the embeded files:
I am using env:p2eincfilepath because that is the powershell method of accessing environment variables and the application appears to create or use an environment variable. Please let me know if there is any other information you might need. The Ps1 appears to work correctly if I run it directly from powershell and put the files in the root directory, calling them with ./ I would really like to keep this function in use since this is what gives me my status bar letting the user know what is being installed:
I think you need to have a $ sign in front of the env variable for it to fill in. e.g.
$NETfile = "$env:p2eincfilepath\1 - NDP471-KB4033342-x86-x64-AllOS-ENU.exe"
$NETargs = "/q"
$SQLfile = "$env:p2eincfilepath\setup.exe"
$SQLargs = "/ConfigurationFile=`".\ConfigurationFile_SQLExpress.ini`""
I want to write a script that loads a url (eg. http://google.com) automatically. But I don't want to install any 3rd party libraries or programs to the server. what's the easiest way to do this?
I just my options are batch script, vb script or powershell right?
FYI from PowerShell, if you want to retrieve the contents of the URL you can do this;
$page = (new-object net.webclient).DownloadString("http://www.bing.com")
$page # writes the contents to the console
If you just want to open it in a browser:
Start-Process http://www.bing.com
Or using the start alias
start http://www.bing.com
Start-Process is new in PowerShell 2.0.
The beauty of Powershell is it has so many ways to do something.
This is my Powershell 2.0 example code - consisting of a Pause function to allow the site to open. It uses Internet Explorer as the browser. In this case - IE is a better browser than the others because it integrates with Powershell through a verbose API.
$url = "http://www.google.com/"
$ie = new-object -com "InternetExplorer.Application"
$ie.Navigate($url)
There are many different functions attached to this object. I recommend loading up the Powershell command line, typing in the above code, and checking what other functions this object has. Type $ie. and pressing TAB iterates through all the methods of this library.
The more I learn of Powershell, the more exciting it becomes. There is nothing it cannot do on Windows.
you can use vbscript
url="http://somewhere.com"
Set objHTTP = CreateObject( "WinHttp.WinHttpRequest.5.1" )
objHTTP.Open "GET", url, False
objHTTP.Send
wscript.Echo objHTTP.ResponseText
objFile.Close
I'm running a Windows Service (Hudson) which in turn spawns a PowerShell process to run my custom PowerShell commands. Part of my script is to unzip a file using CopyHere. When I run this script locally, I see a progress dialog pop up as the files are extracted and copied. However, when this runs under the service, it hangs at the point where a dialog would otherwise appear.
Here's the unzip portion of my script.
# Extract the contents of a zip file to a folder
function Extract-Zip {
param([string]$zipFilePath, [string]$destination)
if(test-path($zipFilePath)) {
$shellApplication = new-object -com shell.application
$zipFile = get-item $zipFilePath
$zipFolder = $shellApplication.NameSpace($zipFile.fullname)
$destinationFile = get-item $destination
$destinationFolder = $shellApplication.NameSpace($destinationFile.fullname)
$destinationFolder.CopyHere($zipFolder.Items())
}
}
I suspect that because its running under a service process which is headless (no interaction with the desktop), its somehow stuck trying to display a dialog.
Is there a way around this?
If it's still actual, I managed to fix this with having CopyHere params equal 1564.
So in my case extract zip function looks like:
function Expand-ZIPFile{
param(
$file, $destination
)
$shell = new-object -com shell.application
$zip = $shell.NameSpace($file)
foreach($item in $zip.items())
{
$shell.Namespace($destination).copyhere($item,1564)
"$($item.path) extracted"
}
1564 description can be found here - http://msdn.microsoft.com/en-us/library/windows/desktop/bb787866(v=vs.85).aspx:
(4) Do not display a progress dialog box.
(8) Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.
(16) Respond with "Yes to All" for any dialog box that is displayed.
(512) Do not confirm the creation of a new directory if the operation requires one to be created.
(1024) Do not display a user interface if an error occurs.
If this is running on Vista or Windows 7, popping up UI from a service isn't going to be seen by the end user as you suspected. See this paper on Session 0 Isolation. However, does the progress dialog require user input? If not, I wouldn't think that would cause the service to hang. I would look for an option to disable the progress display. If you can't find that, then try switching to another ZIP extractor. PSCX 1.2 comes with an Expand-Archive cmdlet. I'm sure there are also others available.
Looking at the documentation for PowerShell, it looks like the -NonInteractive option may help here