none
How to log setup.exe output

    Question

  • Hi,

    How should I run SQL Server Setup.exe in powershell?  I have tried Start-Process, but I have a hard time logging the output.  I am using start-transcript to log the console output.  Is there a way to force the setup.exe output to the console to be logged in the transcript?  Do I log setup.exe output to a file and then output it to the console?  

    Thanks.


    Randy in Marin
    Saturday, May 28, 2011 3:29 AM

All replies

  • SQL Server setup programs write verbose log files in a folder similar to "c:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Log", with apparently separate folders here for each installation. There is an optional command line switch, /INDICATEPROGESS, that specifies the verbose log is piped to the console. Perhaps using this will allow you to capture the verbose log output. For command line details for SQL Server 2008 R2, see this link:

    http://msdn.microsoft.com/en-us/library/ms144259.aspx

    You will need to check the syntax for your version.

     

     


    Richard Mueller - MVP Directory Services
    Saturday, May 28, 2011 9:23 PM
  • Thanks.  I was planning on copying the bootstrap setup file as well if there is an error.  I have a cmd version of a SQL setup network install.  It logs the simple output which will have a short error message if there is an error.  If there is an error, the verbose log files are copied to the share for later examination.  In batch, I see a message that the setup started.  I don't see this in powershell.  If I don't use "-nonewwindow", I will see the message in the new window.  I don't know how to pipe this output to the original window to be catured in the start-transcript log file. 
    Randy in Marin
    Sunday, May 29, 2011 3:29 PM
  • Hi Randy,

    I tried doing a test instance installed (only SQL) through cmd.exe and powershell.exe. I found no difference in behavior if 1. I use /INDICATEPROGRESS  2. Pipe the output to a file using '>' along with that switch 3. Don't use that switch

    What version of SQL you are deploying? Also, lets dig more into the scenario so that I can reproduce the exact behavior.


    Ketan Thakkar | Microsoft Online Community Support
    Thursday, June 09, 2011 11:02 AM
    Moderator
  • Hi Ketan, I have an old cmd version that redirects to a tmp file and then reads the file to include it in the log and display.  With powershell I was trying to go the next step and trying to get the output to the console while the transcript was logging.  I was hoping to see the output as it was generated rather than waiting for setup to exit - setup can take a long time.  I could not get it to do this by just running setup. 

    I ended up creating a process and using the events to get std and err output.  More work, but I'm also able to output a dot every ten seconds so that there is something to watch when really bored.  I'll post what I did when I get bact to the office - I'm on vacation. 

    Thanks. 


    Randy in Marin
    Friday, June 10, 2011 3:27 PM
  • Hi Randy,

    Any update?


    Ketan Thakkar | Microsoft Online Community Support
    Monday, June 20, 2011 10:50 AM
    Moderator
  • Hi Ketan, here is what I ended up doing.  This is not the complete script, so it won't run as is.  It is a lot of extra work to get output before setup.exe finishes.  It would be a lot nicer if powershell was able to handle the setup.exe output asynchronously within the same console window that setup.exe is executed.  Or perhaps it can and I'm missing a bit or two.

    I used a mutex at first to insure the events and loop did not collide, but I removed it because the event code seems to execute with the same thread.  I probably should use a try-catch-finally for running the process to insure the events are unregistered and the process is closed.    

    ...
    
    if (!(test-path variable:\psISE)) {
      start-transcript -path $log
    }
    
    ...
    
    # do the install
    
    $summaryfile = "$env:ProgramFiles\Microsoft SQL Server\100\Setup Bootstrap\Log\Summary.txt"
    
    foreach ($instance in $instances) {
    
      $arguments = $instanceArguments.item($instance)
      Write-Host "Installing $instance instance..."
      Write-Host "Creating process info object..."
    	
      $info = New-Object System.Diagnostics.ProcessStartInfo -Property @{
      	"FileName" = $Command
            "Arguments" = $Arguments
    	"UseShellExecute" = $false
    	"RedirectStandardOutput" = $true
    	"RedirectStandardError" = $true
      }
    
      Write-Host "Creating process object..."
    
      $pr = New-Object System.Diagnostics.Process
    	
      $pr.StartInfo = $info
    
      Write-Host "Registering process events..."
    
      Register-ObjectEvent -InputObject $pr -EventName OutputDataReceived `
        -action {
          if (-not [String]::IsNullOrEmpty($Event.SourceEventArgs.Data)) {
            if ($dotcount -ge 0) {Write-Host; set-variable -name dotcount -value 0 -scope 1}
            Write-Host $Event.SourceEventArgs.Data
          }
        } | out-null
        
      Register-ObjectEvent -InputObject $pr -EventName ErrorDataReceived `
        -action {
          if (-not [String]::IsNullOrEmpty($Event.SourceEventArgs.Data)) {
            $dotcount = get-variable -name dotcount -scope 1
            if ($dotcount -gt 0) {Write-Host; set-variable -name dotcount -value 0 -scope 1}
            Write-Host $Event.SourceEventArgs.Data -foregroundcolor $Host.PrivateData.ErrorForegroundColor -backgroundcolor $Host.PrivateData.ErrorBackgroundColor
          }
        } | out-null
        
      Register-ObjectEvent -InputObject $pr -EventName Exited `
        -action {
          Write-Host "Process exit event detected."; 
          If ($pr -ne $null) {
            $dotcount = get-variable -name dotcount -scope 1
            if ($dotcount -gt 0) {Write-Host; set-variable -name dotcount -value 0 -scope 1}
            Write-Host "Cancelling async read of std output..."
            $pr.CancelOutputRead()
            if ($dotcount -gt 0) {Write-Host; set-variable -name dotcount -value 0 -scope 1}
            Write-Host "Cancelling async read of err output..."
            $pr.CancelErrorRead()
        }
      } | out-null
        
      Write-Host "Starting process..."
    
      $dotcount = 0
    
      [boolean]$started = $pr.start()
      
      Write-Host "Starting async read of std output..."
    
      $pr.BeginOutputReadLine()
    
      Write-Host "Starting async read of err output..."
    
      $pr.BeginErrorReadLine()
      
      Write-Host "Starting monitor loop..."
      Write-Host 'Note: The loop outputs a "." every 10 seconds while waiting for setup.exe to exit.'
    
      $i = 0; 
      while (-not $pr.HasExited)
      {
        $i += $i
        if ($i % 10 -eq 0) {
          if ($dotcount -ge 60 -or $dotcount -eq 0) {write-host; $dotcount = 0}
          Write-Host "." -noNewLine
          $dotcount += 1
         }
    
      	Start-Sleep 10
      	$pr.Refresh();
      }
      
      $exitcode = $pr.ExitCode
      
      Write-Host "Unregistering events..."
      Get-EventSubscriber | `
        ?{@("OutputDataReceived", "ErrorDataReceived", "Exited") -contains $_.EventName} | `
          Unregister-Event
      
      Write-Host "Checking exit code..."
     	Write-host "Process Exited With Error Code: $exitcode"
      
      Write-Host "Closing process..."
    
      $pr.close()
      
      if (Test-Path $summaryfile -pathType leaf) {
        Write-Host "Copying $summaryfile`..."
        $filename = [System.IO.Path]::GetFileNameWithoutExtension($summaryfile) `
          + "`$" + $instance + [System.IO.Path]::GetExtension($summaryfile)
        $summaryfileCopy = [System.IO.Path]::ChangeExtension($log, $filename) 
        Copy-Item $summaryfile $summaryfileCopy
        Write-Host "Content of $summaryfile`..."
        Get-Content $summaryfile
      } 
      
      Write-Host "Checking exit code..."
      if ($exitcode -ne 0) {
        Write-Host "Exiting loop due to error..."
        break
      }
    
    } 
    
    if ($exitcode -ne 0) {
      write-host "Terminating due to error"
    } else {
      write-host "Done - no errors detected"
    }
    
    # stop the transcripting to the log file
    
    if (!(test-path variable:\psISE)) {
      Write-host "Stoping transcript...";
      stop-transcript –ea SilentlyContinue
      [string]::Join("`r`n",(Get-Content "$log")) | Out-File "$log"
      }
    
    
    


     

     

     


    Randy in Marin
    Monday, June 20, 2011 4:04 PM
  • Hi,

    There is some similar feedback to Powershell team around this and its still under observation:

    https://connect.microsoft.com/PowerShell/feedback/details/315875/unable-to-capture-all-session-output-into-a-transcript

    There are couple of suggestions in workaround section, see if that fits into your scenario.

     


    Ketan Thakkar | Microsoft Online Community Support
    Friday, July 01, 2011 7:02 AM
    Moderator