0

I've intentionally written an error in the following:

Try
{
Start-Transcript -Path $Errorlog

#$TermRep = Import-Csv $TermReport
#$Donna = Import-Csv $HRReport

$TermRep = Import-Csv $Path\TestFileTerm2.csv
$Donna = Import-Csv $Path\TestFileDonna.csv

#Job to match users between CSVs
$Job = ForEach($i in $TermRep){
$TID = $($i.'Person ID')
ForEach($u in $Donna){
$DID = $($u.UserID)
If($TID -eq $DID){
"Move-ADObject -Identity $TID -TargetPath 'PATH' `r`n"
            }
    }
}
Stop-Transcript
#Send email of results or statement of no results
$smtpServer = "blah.net"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $EmailFrom
$msg.To.Add($EmailTo)
#$msg.To.Add($EmailTo1)
#$msg.To.Add($EmailTo2)
$msg.Priority = "High"
If($Job -notlike ""){
$msg.Subject = "Open a ticket for Terminated Exception Users for Lit-hold changes."
$msg.Body = "Fix these users"
}
Else{
$msg.Subject = "Terminated Exception Users Script was run for Lit-holds"
$msg.Body = "No users need fixing."
}
$smtp.Send($msg)
}
Catch [system.exception]
{
#If the script errors (e.g. it cannot find one of the lists) send the following email.
$smtpServer = "blah.net"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $EmailFrom
$msg.To.Add($EmailTo)
#$msg.To.Add($EmailTo1)
#$msg.To.Add($EmailTo2)
$msg.Priority = "High"
$msg.Subject = "Open a ticket for Terminated Exception Users - Script Failure"
$msg.Body = "Script error."
$smtp.Send($msg)
}

Specifically, $TermRep = Import-Csv $Path\TestFileTerm2.csv does not exist. However, my transcript comes back as the following:

**********************
Windows PowerShell Transcript Start
Start time: 20151223165030
Username  : DOMAIN\Username 
Machine   : WKSTNName (Microsoft Windows NT 6.1.7601 Service Pack 1) 
**********************
Transcript started, output file is D:\DIR\LogFile2015-12-23.log
**********************
Windows PowerShell Transcript End
End time: 20151223165030
**********************

Can anyone tell me what I'm missing? Do I not understand how Start-Transcript works?

If someone can help me, all I'm trying to do is get an error log to file.

Updated Attempts

I tried changing it to:

Try{$TermRep = Import-Csv $Path\TestFileTerm.csv -verbose -EA stop}
Catch { Write "$DateTime Error: Import-Csv: $_" >>$Errorlog}

If I set each command to try-catch it prints the errors to the log file, but it no longer runs the error email function (2nd email) even when I try to import a non-existent CSV. Instead it runs the Else on the first email, which means no users were found.

Further, Matt's suggestion, when tried prints the errors to the log file, but causes it to always send the error email (2nd email), even when there is no error:

try{
    Start-Transcript -Path c:\temp\text.txt
    $TermRep = Import-Csv $Path\TestFileTerm2.csv
} catch {
    $Error[0]
}
Community
  • 1
  • 1
Nate
  • 802
  • 1
  • 8
  • 28
  • What are you expecting to see that you are not seeing? – dfundako Dec 23 '15 at 22:46
  • @dfundako I'd expect to see something like the error message telling me it cannot import the csv because the file doesn't exist. – Nate Dec 23 '15 at 23:18
  • What is the state of `$ErrorActionPreference`? – Matt Dec 23 '15 at 23:52
  • 1
    Possible duplicate of [start-Transcript not capturing all output to log file..?](http://stackoverflow.com/questions/13160759/start-transcript-not-capturing-all-output-to-log-file) – Eris Dec 24 '15 at 00:28
  • @Matt It's set to "Continue" – Nate Dec 24 '15 at 14:14
  • 1
    @Eris I don't think this is a duplicate, the accepted solution is a link to a page that isn't found, and output in the question is more than I get. – Nate Dec 24 '15 at 14:28
  • Going to test but I wonder if it is because of your try block not having a catch. This code is not usable as it does not have a catch ... presumably you have one, else you would have a syntax error, so that might be where the error is going to. – Matt Dec 24 '15 at 14:54
  • Yep, I have a catch, it just wasn't important for this part. – Nate Dec 24 '15 at 15:00
  • I've just encompassed each step like this instead: `Try{$TermRep = Import-Csv $Path\TestFileTerm.csv -verbose -EA stop} Catch { Write "$DateTime Error: Import-Csv: $_" >>$Errorlog}` until someone can think of a better way to do it. – Nate Dec 24 '15 at 15:01
  • It is if you want us to reproduce your coed – Matt Dec 24 '15 at 15:01
  • The Catch just says `Catch [system.exception]{` and sends an email stating there's an error. – Nate Dec 24 '15 at 15:16
  • You transcript is doing what you told it to. I am also feeling like this is starting to become an XY problem. At the end of the day are you just trying to send the error in the email? You are not using the transcript file contents in your code so I don't see the point exactly. – Matt Dec 24 '15 at 16:09
  • I don't want to send the error in the email. I want create a log for each time the script is run (daily) to sit in the directory of the script. I expected that if I `start-transcript` and then try a bogus `import-csv` I would get the error telling me it can't be opened/no such file. – Nate Dec 24 '15 at 16:15
  • Alright then. If that is the case then my answer covers that. – Matt Dec 24 '15 at 16:19
  • @Matt thanks for sticking with me. I've updated with my two attempts (one is your suggestion) to explain the error I get when I try those. – Nate Dec 24 '15 at 16:39
  • Why not use `Start-Process`? http://stackoverflow.com/questions/11531068/powershell-capturing-standard-out-and-error-with-process-object – Eris Dec 24 '15 at 17:12
  • Change your test to `if($job){}` and zero it out at the start of the file `$job = $null`. You problem about transcript is solved already really. Now we are going back to you past question about the the of `$job` – Matt Dec 24 '15 at 18:50

2 Answers2

0

The important part that you have omitted quite possibly contains your answer. You have the try block trapping the errors. If you are not then outputting inside the catch block you would see the output you show.

try{
    Start-Transcript -Path c:\temp\text.txt
    $TermRep = Import-Csv $Path\TestFileTerm2.csv
} catch {
}

Stop-Transcript

The above would not show the errors Transcript or no. If you were to then output the error in the catch block (similar to what you did in comments) then you would see the error. If you have done something similar you are not showing it.

try{
    Start-Transcript -Path c:\temp\text.txt
    $TermRep = Import-Csv $Path\TestFileTerm2.csv
} catch {
    $Error[0]
}

Stop-Transcript

Keep in mind that this will only show the last error. Not sure how you want to play this for multiple errors. The try catch is meant to capture one this that you expect to fail not several.


My $ErrorActionPreference is set to Continue for what it is worth.

PS C:\temp> $ErrorActionPreference
Continue
Matt
  • 45,022
  • 8
  • 78
  • 119
  • I added my entire code sans `$msg.body`. If I `try-catch` any specific error and output to file, it doesn't send the error email. It sends the email that says there's nothing to process - the `Else` version of the first email, as opposed to the second scripted email. I guess that makes sense, since it's replacing the error? That's why I was originally just looking for some way to write everything it does for that small section, regardless of if it fails or succeeds. – Nate Dec 24 '15 at 15:42
0

I've seen this as well when calling external applications (like dotnet.exe), with .NET exceptions being shown in the console, but not logged in the transcript file.

The fix I found was to redirect the error stream, when calling the external command, like the following:

Start-Transcript log.txt
dotnet.exe asdf 2>&1
Stop-Transcript

With the redirect, the error from dotnet.exe is included in the transcript - without redirection, the "asdf is an unknown command" error would only be shown in the console.

tholesen
  • 460
  • 5
  • 10