Solved

PowerShell Logging

Posted on 2014-10-08
14
203 Views
Last Modified: 2014-10-17
I have a script that runs a sql script to import data. I can't get it to write errors to a log file though. I have tried out-file. Can someone please help? Code below
Function Import-MySQLDatabase{

        param(

        [string]$LoginPath,
        [string]$Database
  
)
     
     #Set variables
      $Date = Get-Date -UFormat "%m%d%Y"
      $Timestamp = Get-Date
      $MySQL = "MySQLpath\mysql.exe" 
      $SQLDrop = "ScriptPath\dropAllTablesAndViews.sql"
      $SQLFirst = "ScriptPath\First_Deployment_part1.sql"
      $SQLCreate = "ScriptPath\Create_Tables.sql"
      $PreRefresh = "ScriptPath\PreRefresh.sql"     
      $SQLDataFile="FilePath\SQL_Dump_$Date.sql"
      $LogFile ="LogPath\ImportStatus_$Date.txt"
      $MySQLErrorLog = "Logpath\Errors_$Date.txt"    
      
      Try{      
      Add-Content $Logfile -Value "Running script $Prerefresh"                                   
      &$mysql --login-path=$LoginPath --database=$Database -e "source $PreRefresh" 
                                                                                                                   
      Add-Content $Logfile -Value "Dropping tables..."                                              
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLDrop"                  
        
      Add-Content $Logfile -Value "Table drop complete. Creating first tables"                        
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLFirst"                  

      Add-Content $Logfile -Value "First tables complete. Creating additional tables..."             
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLCreate"              
 
      Add-Content $Logfile -Value "Beginning data import on $Timestamp"  
      Add-Content $Logfile -Value "Importing data..."
      Set-Location "MySQLInstallation\bin\" 
      &cmd /c "MySQL --login-path=$LoginPath -D$Database < $SQLDataFile" 
      }
      Catch{
     
      Write-Output Error[0] | Out-File $MySQLErrorLog
                    
      }
         
       $Timestamp1 = Get-Date
       Add-Content $Logfile -Value "Data import completed on $Timestamp1"
       

}

Open in new window

0
Comment
Question by:AshleySPM
  • 7
  • 6
14 Comments
 
LVL 1

Author Comment

by:AshleySPM
ID: 40368558
That did not seem to work. Is there anything wrong with my syntax anywhere? I saw this work briefly yesterday and then started messing around with the script and I can't get it to work again
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40368590
Maybe something like this will work?

Catch{
$ExceptionName = $_.Exception.GetType().FullName; 
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-Output $ExceptionName $ErrorMessage $FailedItem | Add-Content $MySQLErrorLog
}

Open in new window

0
 
LVL 1

Author Comment

by:AshleySPM
ID: 40368601
&$mysql --login-path=$LoginPath --database=$Database -e "source $PreRefresh"  2>$MySQLErrorLog
                                                                                                                   
      Add-Content $Logfile -Value "Dropping tables..."                                              
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLDrop" 2>>$MySQLErrorLog                
       
      Add-Content $Logfile -Value "Table drop complete. Creating first tables"                        
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLFirst" 2>>$MySQLErrorLog                  

      Add-Content $Logfile -Value "First tables complete. Creating additional tables..."            
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLCreate" 2>>$MySQLErrorLog            
 
      Add-Content $Logfile -Value "Beginning data import on $Timestamp"  
      Add-Content $Logfile -Value "Importing data..."
      Set-Location "MySQLInstallation\bin\"
      &cmd /c "MySQL --login-path=$LoginPath -D$Database < $SQLDataFile"  2>>$MySQLErrorLog
0
 
LVL 1

Author Comment

by:AshleySPM
ID: 40368604
The above worked for me but I'll try yours since it could definitely be cleaner output
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40368614
Yes, I was going to suggest that but It is very difficult to use. Ive had to look through an output file generated like that, it took me 2 days. It was also several thousand lines and using the "Find" tool lol
0
 
LVL 1

Author Comment

by:AshleySPM
ID: 40368620
Sadly no luck with that
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40368635
Maybe this will work, keep it simple

$error[0] | Add-Content $MySQLErrorLog
0
[Webinar] Disaster Recovery and Cloud Management

Learn from Unigma and CloudBerry industry veterans which providers are best for certain use cases and how to lower cloud costs, how to grow your Managed Services practice in IaaS clouds, and how to utilize public cloud for Disaster Recovery

 
LVL 1

Author Comment

by:AshleySPM
ID: 40368707
Like this?
Try{
Do stuff
}
Catch{
      $error[0] | Add-Content $MySQLErrorLog 
      }

Open in new window

0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40368718
yea, I tried it and it worked for me using a single command.

EDIT: Ive also added some returns to help separate the errors and a clear at the end to remove all errors from the session.

try { get-aduser "FakeUser" }
catch { "`n`n" | Add-Content "C:\ErrorLog.txt" 
$error | Add-Content "C:\ErrorLog.txt" }
$error.Clear()

Open in new window

0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40368757
I added to your function

Function Import-MySQLDatabase
{

        param(

        [string]$LoginPath,
        [string]$Database
        )
     
     #Set variables
      $Date = Get-Date -UFormat "%m%d%Y"
      $Timestamp = Get-Date
      $MySQL = "MySQLpath\mysql.exe" 
      $SQLDrop = "ScriptPath\dropAllTablesAndViews.sql"
      $SQLFirst = "ScriptPath\First_Deployment_part1.sql"
      $SQLCreate = "ScriptPath\Create_Tables.sql"
      $PreRefresh = "ScriptPath\PreRefresh.sql"     
      $SQLDataFile="FilePath\SQL_Dump_$Date.sql"
      $LogFile ="LogPath\ImportStatus_$Date.txt"
      $MySQLErrorLog = "Logpath\Errors_$Date.txt"    
      
      Try{      
      Add-Content $Logfile -Value "Running script $Prerefresh"                                   
      &$mysql --login-path=$LoginPath --database=$Database -e "source $PreRefresh" 
                                                                                                                   
      Add-Content $Logfile -Value "Dropping tables..."                                              
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLDrop"                  
        
      Add-Content $Logfile -Value "Table drop complete. Creating first tables"                        
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLFirst"                  

      Add-Content $Logfile -Value "First tables complete. Creating additional tables..."             
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLCreate"              
 
      Add-Content $Logfile -Value "Beginning data import on $Timestamp"  
      Add-Content $Logfile -Value "Importing data..."
      Set-Location "MySQLInstallation\bin\" 
      &cmd /c "MySQL --login-path=$LoginPath -D$Database < $SQLDataFile" 
      }
      Catch { 
      "`n`n" | Add-Content $MySQLErrorLog
      $error | Add-Content $MySQLErrorLog
      $error.Clear()
      }
      
      $Timestamp1 = Get-Date
      Add-Content $Logfile -Value "Data import completed on $Timestamp1"
}

Open in new window

0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40369050
Any luck Ashley?
0
 
LVL 1

Author Comment

by:AshleySPM
ID: 40369123
Nope
0
 
LVL 68

Accepted Solution

by:
Qlemo earned 500 total points
ID: 40371842
For using try/catch you need a stopping error, so the complete command fails. I reckon mysql will not throw fatal errors (or exceptions), but outputs errors to stdout only.
Just as a note, if $mysql does not result in an executable name, the catch gets triggered.

Indeed there is no other way than to redirect stderr to stdout or a file to get the error messages.
You can add the redirection to each command, similar as you have done already, or apply it to a script or block:
$(
      &$mysql --login-path=$LoginPath --database=$Database -e "source $PreRefresh" 
                                                                                                                   
      Add-Content $Logfile -Value "Dropping tables..."                                              
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLDrop"                  
        
      Add-Content $Logfile -Value "Table drop complete. Creating first tables"                        
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLFirst"                  

      Add-Content $Logfile -Value "First tables complete. Creating additional tables..."             
      &$mysql --login-path=$LoginPath --database=$Database -e "source $SQLCreate"              
 
      Add-Content $Logfile -Value "Beginning data import on $Timestamp"  
      Add-Content $Logfile -Value "Importing data..."
      Set-Location "MySQLInstallation\bin\" 
      &cmd /c "MySQL --login-path=$LoginPath -D$Database < $SQLDataFile" 
) 2>&1 | out-file $MySQLErrorLog

Open in new window

But I would write the output to one file, to have the command sequence and timing in view when an error is reported.
0
 
LVL 1

Author Comment

by:AshleySPM
ID: 40382951
Thank you I will try that!
0

Featured Post

Zoho SalesIQ

Hassle-free live chat software re-imagined for business growth. 2 users, always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this previous article (https://oddytee.wordpress.com/2016/05/05/provision-new-office-365-user-and-mailbox-from-exchange-hybrid-via-powershell/), we made basic license assignments to users in O365. When I say basic, the method is the simplest way …
Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

896 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now