View Full Version : Run Program - powershell.exe issue
kboller
06-27-2017, 11:53 AM
Hi,
I have a powershell script that I want to run during the install process. It needs to run with elevated permissions. However at this point that line doesn't appear to do anything. Attached is a screen print of that entry.
Thanks,
Kurt
linder
06-28-2017, 03:28 AM
Hello Kurt,
1. If your installer is using the default requireAdministrator execution level, please do not mark the "Run elevated from non-elevated SetupBuilder application" option. You only need this if your setup.exe is running non-elevated.
2. You are using the ShellExecuteEx Windows API to run powershell.exe. So please use fully qualified path names here! Otherwise, ShellExecute can't do what you want. In the "Target Folder" entry field, please enter the path to the powershell.exe!
For example, %SYS32DIR%\WindowsPowerShell\v1.0
There is a fundamental difference between calling an application from a Windows API and from a command line interpreter. So you might also have to modify your Command Line field. Not sure if the Windows ShellExecute API can handle your ".\InstallFiles\NETWMF yada yada" argument. Perhaps you also need fully qualified pathnames here.
Hope this helps a bit.
Friedrich
kboller
11-09-2017, 01:20 PM
Still having an issue with Powershell. I am trying to run a PowerShell script shortly after starting my installer. SetupBuilder copies the script to a temporary folder %TEMP%\FacilityDocs and then calls for it shortly after. I am able to get the script to run fine if I just copy the command into a regular PowerShell prompt but I cannot get it to run properly using SetupBuilder’s “Run Program”. I have attached a screencap of my current settings and the error I’m getting when trying to run the installer. This is the command that is being run (it got cut off in the screencap):
Start-Process PowerShell -ArgumentList "-ExecutionPolicy Bypass -File $Env:Tmp\Facilitydocs\PreCheck.ps1" -Verb RunAs
4679
4680
Below is the PowerShell script in case it would help. This script must run elevated.
<### New Environment variable notes:
FDinstall: Continue/Cancel
- Indicates whether SetupBuilder will continue or cancel install after this "Pre-Check" script is run
NETstat: (Pass/Fail)
- Indicates whether the .NET framework is installed
NETvers: (Pass/Fail)
- Indicates whether the .NET framework is on the required version or newer
NETRSreq: (Yes/No)
- Indicates whether the installation of .NET will require SetupBuilder to execute a restart command
SQLbrDefStat: (Variable)
- SQLBrowser default (existing) status in case the installer is cancelled (to revert to old settings)
SQLbrDefStartup: (Variable)
- SQLBrowser default (existing) startup mode in case the installer is cancelled (to revert to old settings)
SQLstat: (Pass/Fail)
- Indicates whether SQL server is installed on the local machine
SQLuser: (SB) (Variable)
- User defined SQL username
SQLpw: (SB) (Variable)
- User defined SQL password
SQLinstall: (SB) (New/Existing)
- If SQL is installed, user selection to install FacilityDocs as a new instance or use the existing instance
SQLserver: (SB) (Variable)
- Get-ServerName script returns this variable after checking against instance name
SQLinst: (SB) (Variable)
- User defined SQL instance name
SQLauth: (SB) (MM/Win)
- User defined SQL authentication method
LclSQLinstance: (Variable)
- Stores detected SQL instance names on local machine
#>
Function Out-IniFile
{
[CmdletBinding()]
Param
(
[switch]$Append,
[ValidateSet("Unicode","UTF7","UTF8","UTF32","ASCII","BigEndianUnicode","Default","OEM")]
[Parameter()]
[string]$Encoding = "Unicode",
[ValidateNotNullOrEmpty()]
[ValidatePattern('^([a-zA-Z]\:)?.+\.ini$')]
[Parameter(Mandatory=$True)]
[string]$FilePath,
[switch]$Force,
[ValidateNotNullOrEmpty()]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[Hashtable]$InputObject,
[switch]$Passthru
)
Begin
{Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started"}
Process
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing to file: $Filepath"
if ($append) {$outfile = Get-Item $FilePath}
else {$outFile = New-Item -ItemType file -Path $Filepath -Force:$Force}
if (!($outFile)) {Throw "Could not create File"}
foreach ($i in $InputObject.keys)
{
if (!($($InputObject[$i].GetType().Name) -eq "Hashtable"))
{
#No Sections
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing key: $i"
Add-Content -Path $outFile -Value "$i=$($InputObject[$i])" -Encoding $Encoding
}
else
{
#Sections
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing Section: [$i]"
Add-Content -Path $outFile -Value "[$i]" -Encoding $Encoding
Foreach ($j in $($InputObject[$i].keys | Sort-Object))
{
if ($j -match "^Comment[\d]+")
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing comment: $j"
Add-Content -Path $outFile -Value "$($InputObject[$i][$j])" -Encoding $Encoding
}
else
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing key: $j"
Add-Content -Path $outFile -Value "$j=$($InputObject[$i][$j])" -Encoding $Encoding
}
}
Add-Content -Path $outFile -Value "" -Encoding $Encoding
}
}
Write-Verbose "$($MyInvocation.MyCommand.Name):: Finished Writing to file: $path"
if ($PassThru) {Return $outFile}
}
End
{Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"}
}
"Checking system status. Please wait..."
### Assemblies and Modules
Add-Type -AssemblyName PresentationFramework
Import-Module BitsTransfer
<### Windows version check
$OSversionMajor = [Environment]::OSVersion.Version.Major
$OSversionMinor = [Environment]::OSversion.Version.Minor
$OSversionBit = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
#> # Not needed as of 11-07-17
$FDinstall = "Continue"
### Microsoft .NET Version Check - Set .NET status environment variables and indicate whether .NET install requires restart
$NETrelease = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\' -Name Release -ErrorAction SilentlyContinue -ErrorVariable evNETrelease).release
$NETinstalled = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\' -Name Install -ErrorAction SilentlyContinue -ErrorVariable evNETinstalled).install
If($evNETrelease -or $evNETinstalled)
{
$NETstat = "Fail"
$NETvers = "Fail"
$NETRSreq = "Yes"
}
Elseif (($NETinstalled -ne 1) -or ($NETrelease -lt 379893))
{
$NETstat = "Fail"
$NETvers = "Fail"
$NETRSreq = "Yes"
}
Else
{
$NETstat = "Pass"
$NETvers = "Pass"
$NETRSreq = "No"
}
### Microsoft SQL check - Set SQL status environment variables, enable SQLBrowser service, and test for existing instances
"Checking SQL Path..."
If((Test-Path 'HKLM:\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL') -eq "True")
{
try
{
"Checking Microsoft SQL status. Please wait..."
$SQLstat = "Pass"
$SQLbrDefStat = (Get-Service SQLBrowser).Status
$SQLbrDefStartup = (Get-WmiObject -Class Win32_Service -Filter "Name='SQLBrowser'").StartMode
Set-Service SQLBrowser -StartupType Manual
Set-Service SQLBrowser -Status Running
$LclSQLinstance = ([System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources() | Where {$_.ServerName -eq $env:COMPUTERNAME}).InstanceName -replace (" ","|")
}
Catch
{
$FDinstall = "Cancel"
[System.Windows.MessageBox]::Show("FacilityDocs installer encountered an error. Please contact Bronze Bow Software support for further assistance.","ERROR","Ok","Error")
}
}
Else
{
"Could not find SQL path"
$SQLstat = "Fail"
}
# Create INI config file
$Config = @{"FDinstall"=$FDinstall;"NetStat"=$NETstat;"NetVers"=$NETvers;"NetRSreq"=$NETRSreq;"SQLbrDefStat"=$SQLbrDefStat;"SQLbrDefStartup"=$SQLbrDefStartup;"SQLstat"=$SQLstat;"SQLuser"="";"SQLinstall"="";"SQLserver"=$env:COMPUTERNAME;"SQLinst"="";"SQLauth"="";"LclSQLinstance"=$LclSQLinstance}
$NewINIContent = @{“Config”=$Config}
Out-IniFile -InputObject $NewINIContent -FilePath "$Env:Tmp\FacilityDocs\FDconfiguration.INI" -Force
Start-Sleep -Seconds 5
kboller
11-09-2017, 01:24 PM
Here is a better image of the error I receive when running the script from powershell.4681
linder
11-10-2017, 10:18 AM
Kurt,
I am afraid I don't know how to help in your specific case. SetupBuilder simply uses the Windows CreateProcess API (to start PowerShell) and passes the parameters that you defined to the Windows API. In other words, SB launches Powershell and waits until it terminates (powershell handles the script processing). If this fails then at least one of the parameters passed to PowerShell is not correct.
Friedrich
linder
11-10-2017, 10:22 AM
BTW, if I were you, I would try it again with "Run Command Line...". This will also use the Windows CreateProcessA Windows API. Perhaps this lets you find out what the problem with the powershell script is...
Please keep us posted.
Friedrich
linder
11-10-2017, 10:31 AM
I googled for "A Positional Parameter Cannot Be Found That Accepts Argument Powershell" and there are tons of tips.
Here is one:
When you wrap this script in an executable file and use the same command line, it used to fail, because all input strings were interpreted as parameter values. In this case, ‘-Parameter’ was interpreted as the value of the Word parameter and ‘PowerShell’ was interpreted as the value of the Number parameter. The script failed when Windows PowerShell couldn’t convert ‘PowerShell’ to a integer."
https://www.sapien.com/blog/2015/11/30/passing-parameters-to-a-script-in-an-executable-file/
Perhaps this is similar to your issue?
Friedrich
kboller
11-14-2017, 01:28 PM
I tried the Run Command Line route and it's better however still not working correctly. This is an excerpt from the PowerShell script. When running the batch file manually, everything works fine. But when running the batch file from the SetupBuilder exe, it fails on the highlighted line of code below. For some reason it has an issue querying the registry.
If((Test-Path –Path 'HKLM:\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL') -eq "True")
{
try
{
"Checking Microsoft SQL status. Please wait..."
$SQLstat = "Pass"
$SQLbrDefStat = (Get-Service SQLBrowser).Status
$SQLbrDefStartup = (Get-WmiObject -Class Win32_Service -Filter "Name='SQLBrowser'").StartMode
Set-Service SQLBrowser -StartupType Manual
Set-Service SQLBrowser -Status Running
$LclSQLinstance = ([System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources() | Where {$_.ServerName -eq $env:COMPUTERNAME}).InstanceName -replace (" ","|")
}
Catch
{
$FDinstall = "Cancel"
[System.Windows.MessageBox]::Show("FacilityDocs installer encountered an error. Please contact Bronze Bow Software support for further assistance.","ERROR","Ok","Error")
}
}
Else
{
"Could not find SQL path"
$SQLstat = "Fail"
} 46844685
kboller
11-14-2017, 04:17 PM
So to summarize what's happening (sorry, I should have done that in the last reply). When the batch file is run from an un-elevated command prompt, the script runs fine and is able to query the registry for information about the SQL server that currently exists. However when running the same batch file/script from the Run Command box in setup builder, it can not query the registry for sql server information. Even when UAC is completely turned off, the same results occur.
Thanks,
Kurt
linder
11-15-2017, 05:15 AM
Kurt,
please note that there is a fundamental difference between running a batch file from a command line interpreter and executing it from a Windows application through, say, CreateProcess or ShellExecuteEx Windows APIs. To launch external programs from a Windows application, you have to use CreateProcess or ShellShecute(Ex). In your case, SetupBuilder executes Powershell (gives *complete* control to it) and waits until Powershell returns. If your script fails when executed from a CreateProcess or ShellExecute Windows APIs then there is a problem with the script (this has nothing to do with SetupBuilder). Remember: Powershell executes your script, not SB. For example, your script expects a specific current folder or access to a specific registry branch. To check what the problem in your script is, simply write your own small 32-bit program with Visual C or Delphi or Clarion and call your script with the exact same command line parameters your are currently using in SB (call PS/your script and wait for its termination). I am sure you'll get the very same error.
But if it works from the command line interpreter, why don't you simply call your batch file from the installer in an interpreter? From a Windows program, you do it via CMD.EXE. Just calling the batch without CMD /C is not correct and might fail.
For example:
cmd /C c:\mydir\MyBatch.bat
in a "Run Command Line..." or "Run Program..." SB function.
As a side note: perhaps this is a x64 operating system and your script tries to read a 64-bit registry value, but the value is stored in the 32-bit branch (or vice-versa!). And that's why it fails when running Powershell in 32-bit mode. Maybe it's looking in the wrong registry branch?
32-bit programs and 64-bit programs that are running on a x64-based version of Windows operate in different modes and use the following sections in the registry:
1. Native mode 64-bit programs run in Native mode and access keys and values that are stored in the following registry sub key:
HKEY_LOCAL_MACHINE\Software
2. 32-bit programs run in WOW64 mode and access keys and values that are stored in the following registry sub key:
HKEY_LOCAL_MACHINE\Software\WOW6432node
Does this help a bit?
Friedrich
kboller
11-15-2017, 05:59 AM
The 32-bit program vs 64-bit may be the factor. This is running on a 64-bit system. This brings up more questions:
1) How do you tell which mode the command prompt is running in?
2) Can you tell me which mode (32 vs 64) that the batch file will run in when executed from Setup builder?
3) If that's not the same as running it from the command prompt in Windows, how do I initiate it so that it's the same?
Thanks,
Kurt
linder
11-15-2017, 01:03 PM
Hi Kurt,
if you run a command line interpreter from an application that is running in x86 mode (32-bit processing) then the 32-bit interpreter is executed. In SetupBuilder, you can use the "Set x64 mode..." script function to switch the setup application (at runtime) into 64-bit processing mode. See attached screenshot. After doing this, the setup will execute the 64-bit interpreter. Don't forget to disable x64 mode!
Does this help?
Friedrich
kboller
11-29-2017, 02:41 PM
Hi Friedrich,
It was the difference between running the 32-bit vs 64-bit command prompt that was the issue. That was what I needed to know.
Thank you!,
Kurt
linder
11-30-2017, 04:14 AM
Hi Kurt,
perfect!!! Thanks for the update.
Friedrich
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.