user11861660
user11861660

Reputation: 41

How do I include the username and password in a powershell script running a window service msi

I am setting up powershell scripts to automate environment installs for a variety of systems. I need to script the running of an MSI installer file to setup a Windows Service. How do I include the required Username and Password to make the installation fully 'quiet'

I've gotten to:

$installFile = "C:\[path]\Installer.msi"
$username = "[ad user account]"
$password = convertto-securestring -String "[secure password]" -AsPlainText -Force  

msiexec /i $installFile /quiet "UserName=$username,Password=$password"

but the provided credentials are not being accepted.

Suggestions?

Upvotes: 2

Views: 4142

Answers (2)

user11861660
user11861660

Reputation: 41

First of all, thank you everyone for your help.

Reading through your suggestions and the following question in the list of “Related” suggestions got me thinking in another direction (Msi insaller passing paramenter from command prompt for Set Service Login).

A little more hunting and I found this article: Change Service Account Username & Password–PowerShell Script

So, my new plan is to default the service account inside installer via code and then change it after installation using PowerShell. In the source code for the windows service I have a ProjectInstaller.cs file. Opening the ProjectInstaller.Designer.cs code and looking in the InitializeComponent() method I saw the following lines:

this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;

Adding the following line below successfully suppresses any request for service account credentials during installation:

this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;

After that I used the code sample from the TechNet article to change the account post-installation. The final script looks something like this:

$serviceName = "Service"
$oldInstallFile = "C:\Old_Installer.msi" #Only required if upgrading a previous installation
$installFile = "C:\New_Installer.msi"

$serviceConfigSource = "C:\Config"
$serviceConfigSourceFile = "C:\Config\Service.exe.config"
$serviceConfigDestinationFile = "C:\Program Files (x86)\Service\Service.exe.config"

$username = "[UserName]"
$password = "[Password]"  


#Checking for existing service installation and uninstalling it
$existingService = Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"

if($existingService)
{
    Write-Host "$serviceName found. Begining the uninstall process..."
    if($existingService.Started)
    {
        $existingService.StopService()
        Start-Sleep -Seconds 5
    }

    msiexec /uninstall $oldInstallFile /quiet
    Start-Sleep -Seconds 5
    Write-Host "$serviceName Uninstalled."

}

#Install New service
Write-Host "$serviceName installation starting."
msiexec /i $newInstallFile /quiet
Start-Sleep -Seconds 5
Write-Host "$serviceName installation completed."



#copy config file
if(Test-Path $serviceConfigSource)
{
    Copy-Item -Path $serviceConfigSourceFile -Destination $serviceConfigDestinationFile -Force
}


#Final service setup and start up
$newService = Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"

$changeStatus = $newService.Change($null,$null,$null,$null,$null,$null,$userName,$password,$null,$null,$null) 
if ($changeStatus.ReturnValue -eq "0")  
{
    Write-Host "$serviceName -> Sucessfully Changed User Name"
} 

if(!$newService.Started)
{
    $startStatus = $newService.StartService()
    if ($startStatus.ReturnValue -eq "0")  
    {
        Write-Host "$serviceName -> Service Started Successfully"
    } 

}

Hope this helps people.

Upvotes: 2

Moerwald
Moerwald

Reputation: 11304

Try to seperate your arguments with spaces:

 $installArgs = "UserName=$username Password=$password" 

Afterwards you can call msiexec via:

 $msiArgs = "/i ""{0}"" /qn /norestart /l*v ""C:\temp\msiInstall.log"" {1}" -f $msiLocation,$installArgs
 $process = Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList $msiArgs -Wait -PassThru
 if ($process.ExitCode -ne 0) {
      Write-Error "Installation failed"
 }

Upvotes: 0

Related Questions