2

I have this function:

function traced()
{
    write-host "$args"
    invoke-expression -Command "$args"
}

and I use it in several places like traced cp "$($_.FullName)" (join-path $directory $newfile) so that I have a log of all of the places that get copied (or removed, or whatever)

But when the directory contains spaces and dashes, it results in invoke-expression throwing.

I guess I could just define traced-cp and traced-rm, but if I have a lot of functions I want to trace, what's the generic answer? I just want a function that prints, then evaluates, the exact command its given. From what I understand, the & operator isn't what I want here-- It won't work for shell builtins.

user973223
  • 127
  • 1
  • 8

3 Answers3

2

[...] so that I have a log of all of the places that get copied (or removed, or whatever)

I'd strongly recommend you use transcript logging for this!

You can start a transcript interactively with the Start-Transcript cmdlet, but if you want to keep a transcript of every single instance of PowerShell you launch by default, I'd suggest turning it on by default!

Open the local policy editor (gpedit.msc) on your Windows box and navigate to:

  • Computer Configuration
    • > Administrative Templates
      • > Windows Components
        • > Windows PowerShell

Select the policy setting named "Turn on PowerShell Transcription", set it to Enabled, and optionally configure your preferred output directory (defaults to your home folder).

This way, you'll always have a full transcript of your interactions in PowerShell :)

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
1

Consider using argument splatting to build your command instead of building a string-based command with Invoke-Expression. I also don't know where you heard that & doesn't work with shell built-ins but it works with both commands and cmdlets.

Here is the official Microsoft documentation on splatting in Powershell.

This approach also eliminates the difficulty in crafting a command string correctly, having to escape characters, and dealing with path spaces - using splatting with named or positional arguments takes care of most of this for you.

codewario
  • 19,553
  • 20
  • 90
  • 159
0

I would suggest using -verbose with copy-item or remove-item, and also -passthru with copy-item.

js2010
  • 23,033
  • 6
  • 64
  • 66