Using Out-file

Hi there,

I’ve recently watched the Powershell jumpstart series and I’m getting dangerous. I have a fairly simple script but I have a feeling there’s an easier (more elegant?) way to do this.

My script creates new deployments in a vmware environment and I want a nicely formatted log in a text file for now. The purpose is so the admin running it can see exactly what was done and also for auditing purpose.

My question is putting the out-file $filename -append and the end of just about every line seems a little crazy. Is Start-Transcript a better option? I did see a forum post about Start-Transcript but it didnt to quite apply to my situation.

Param(
[Parameter(Mandatory=$True,Position=1)]
    [string]$ClientName,
[Parameter(Mandatory=$True)]
    [string]$vlanID
) 

$cluster = 'Cluster'
$RootVMFolder = 'Client Folder'
$vSwitch = 'dvswitch'
$numports = 8
$LogFileRoot= "c:\scripts\logs\"
$logfile =($LogFileRoot + $clientname + "-" + (Get-Date -f MMddyyyy-hhmm)  +".log")

Write-Output ("Script Executed by " + $env:username) | out-file $logfile  -append

#Loading credentials for logging into vCenter
$creds = Get-VICredentialStoreItem -file pshell.creds 
Write-Output "Logging into vCenter...." | out-file $logfile  -append
Connect-VIServer -server $creds.host -user $creds.user -password $creds.password | out-file $logfile -append


Write-Output "Creating New Folder for VMs" | out-file $logfile  -append
new-folder -Name $clientName -Location $RootVMFolder  | select Name,Parent | out-file $logfile  -append

Write-Output "Creating New Resource Pool" | out-file $logfile -append
new-resourcepool -Location $cluster -name $clientName  | select Name |  out-file $logfile  -append

Write-Output ("Creating New PortGroup called " + "VPN-" + $ClientName + " with vlanID " + $vlanid) | out-file $logfile  -append
Get-VDSwitch -name "dvSwitch" | New-VDPortgroup -Name VPN-$ClientName -numports $numports -vlanid $vlanId  | out-file $logfile  -append

Maybe, maybe not. Only the console host supports transcripts, so your script would have to be running in it (e.g., not the ISE or another host). Most folks will create a “logging” function to make this a bit neater. Then you just do something like “Write-Log ‘whatever’” and it takes care of outing to the file.

A reply in two minutes, that’s impressive.

Turns out I’m not completely crazy so thanks for that.

Happy New Year!

For simple stuff, I don’t worry about putting logging code in the script itself. I just redirect the script’s output to a file and review it later. For example, in a scheduled task, I might launch:

PowerShell.exe -File c:\somePowerShellScript.ps1 *> c:\Logs\someLogFile.txt

The “*>” operator is available in PowerShell 3.0 and later; it redirects all streams (output, error, warning, verbose and debug) to the same file.

This approach has a couple of limitations. You don’t get to see the output at the console as the script is running; you have to view it in the log file afterward. I also like to have timestamps in my log files. For that reason, I wrote a module to intercept Host output and redirect it to a file, which you can see here, if you’re interested. It works a lot like Start-Transcript, but works with both the ISE and PowerShell.exe hosts (and very possibly with other custom hosts as well, though I haven’t tested it with anything else.) You can also have multiple captures going at once (with different combinations of streams, if desired), whereas there can only be one Start-Transcript active per session.

Clearly I am doing something wrong here as i cannot get the Out-File to write:

$a = Get-Date -format yyyyMMdd-HH:MM
Get-ChildItem -Path z:\ -Filter "$line.pdf" -Recurse | Copy-Item -DESTination c:\Temp -PassThru |Out-File c:\utils\Logs\$a.log

But this one works? Why doezsn’t Out-File take variables???

$a = Get-Date -format yyyyMMdd-HH:MM
Get-ChildItem -Path z:\ -Filter "$line.pdf" -Recurse | Copy-Item -DESTination c:\Temp -PassThru |Out-File c:\utils\Logs\test.log

The problem isn’t the pipe to out-file, it’s this part earlier in the pipeline:

> Write-Verbose

That greater than sign is a redirection operator (which essentially just calls Out-File under the hood anyway.)

Sorry, Dave, I saw that and changed the request. Why can’t I get Out-File to take a variable?

see, I am trying to write a script that will find corrupted files and list them.

Out-File does take variables, but your variable’s value has a colon in it, which isn’t legal in a Windows file name.