Syntax error using [void]

Trying to use [void] to supress output of Move-Item cmdlet:

foreach ( $f in $Files ) {
  [void] Move-Item $f.fullname $TargetPath
}

Error:

At C:\!\!PS\x.ps1:2 char:10
+         [void] Move-Item $f.fullname $TargetPath
+                ~~~~~~~~~
Unexpected token 'Move-Item' in expression or statement.

What's going on here? Thanks.

[edit] I just realized that move-item doesn't produce output if everything works - this snippet was part of a bigger block of code that produced chatter that I needed to void. So I can remove the void, but I'm still interested to know what's going on.

25 comments · 63% upvoted · other discussions

comments

SMFX

In powershell, just use the $null variable in these contexts:

$null = Move-Item $f.fullname $TargetPath
time_keeper_1

I don’t understand this. Why do we assign that action to $null.

SMFX

The $null is a special variable that must always equal nothing. Functionality wise, it's essentially the same as piping to | Out-Null, but has been proven to be exceptionally faster in repetitive loops.

lolinux

When assigning the output stream to a variable, it will no longer be sent to the standard output, but will be saved in the variable.

However be aware that it's just the standard output stream. If there are errors, the error stream will stil be sent to the screen.

In order to make it silent you could Move-Item $file $newname -ErrorAction SilentlyContinue, or capture the error stream into a variable Move-Item $file $newname -ErrorVariable errvar.

Edit: formatting

time_keeper_1

Thank you. This community is great. I’m on my first week of posh from C# and I’m learning a lot.

SMFX

Or, if you are going to do error handling, incorporate try { } catch { } and use -ErrorAction Stop:

Try {
    Move-Item $file $newname -ErrorAction stop
 } Catch {
    #deal with the error like adding a number to the end, creating the folder, retry, etc
 }
lolinux

Yeah, that too is a good idea, since OP knows C#, I imagine error handling should be familiar

[deleted]
jimb2 [OP]

Will do this. I like the look of [void] but not if I have to bracket the cmdlet. My full code was moving huge directories - like 300k files - in to a subfolder structure and needed to create the subfolders like

 [void] [System.IO.Directory]::CreateDirectory( $TargetPath )

The void worked with the dotnet function but not with the cmdlet.

OPconfused

Wrap the cmdlet and parameters in parentheses, e.g., [void](Move-Item ....). The void needs to act on the output, so the parentheses create the output first.

Response to your edit: Are you also trying to suppress the error message with void? You'll have to use the -ErrorAction parameter for that.

jimb2 [OP]

I'm not trying to supress errors. Just the default output.

[deleted]

Weird. I use [void] all the time too I I would think it should not care if there was output or not. I’m glad the parens work…but it still should work without them…

w3lbow

I have always used assignment to $null. For example:

$array = [system.collections.arraylist]::new()
$null = $array.add( 'foo' )

Found it on Google/Stackoverflow way back when to sink useless output.

I use an arraylist when I am building up an array item by item, e.g. iterating over input and building a psobject based on the input and perhaps API calls based on the input, then shoving the psobject into an arraylist for exporting into a file at the end of the script.

jimb2 [OP]

Sure, it works, but just has a weird aesthetic to me - assigning to a system constant - that I'd like to eliminate. I'm a bit ocd - but aren't all self-respecting coders :)

ovdeathiam

Using [void] is declaring that they following object is of that type. You can't set a data object type for a cmdlet because it's not an object. You can set it for cmdlet output though therefore you need to encapsulate the cmdlet in round brackets.

PinchesTheCrab

In PS7 they improved the performance of out-null, which is a bit more intuitive syntax-wise. If you're on PS Core I recommend using out-null instead.

SMFX

Out-Null is better than it was, but that's not saying much.

The | Out-Null just looks better and stylistically is powershellish, but even the docs admit it's not as fast as $null = :

https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-null?view=powershell-7.3#redirect-output-to-null

jimb2 [OP]

Doing nothing would have to be highly optimisable :)

PinchesTheCrab

I think that was the heart of the problem, it still sent data over the pipeline, so you still passed all the output through memory. I assume they rewrote to do closer to nothing.

Scooter_127

I think you need to get rid of the space between [void] and Move-Item

I tend to use things like <whatever> | out-null or $junk = <whatever>

jimb2 [OP]

It's not the space. Out-Null works, but it's a fair bit slower because PS has to set up the pipeline structure. I'm doing a huge number of moves so efficiency counts. $null = is also efficient but [void] looks nicer :)

u/OPconfused is on the money.

TenOf11

I usually look at code like math and utilize the order of operations.

In this case, the code is setting the text "Move-Item" to the type of [void], but I believe you want it to set the output of the entire command to the type of [void], so I would wrap the entire command in parentheses. This would perform the Move-Item operation and then set its output to the type of [void].

[void](Move-Item $f.fullname $TargetPath)

[deleted]

you can cast as void, just throw the script block in brackets and it will suppress any output.

UnfanClub

[void] is a type accelerator. You can use it to cast an object as void. Here's an example:

[void]$silence = Get-Noise

If you want to mute a cmdlet/function call you can pipe to Out-Null

Get-Noise | Out-Null