powershell

powershell: Understanding Move-Item returned value


I am trying to use the UNIX && equivalent in powershell, as explained here, but I fail to understand the syntax.

Could someone please help me understand the returned value from Move-Item in my case. Assuming you do not have a folder named foo and that you have write access to the current folder, I failed to understand why I get a False value here:

> (New-Item -Type Directory -Path foo) -and (Move-Item -Path foo -Destination bar)
False

Since:

> Get-Item bar


    Directory: C:\Users\me


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         1/23/2025   5:17 PM                bar

Using:

> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  4522

It looks like Rename-Item is producing the same symptoms I do not understand:

> (New-Item -Type Directory -Path foo) -and (Rename-Item -Path foo -NewName bar)
False

Solution

  • You have one cmdlet that produces output by default (New-Item) and other cmdlet that produces no output (Move-Item) unless you use -PassThru.

    So if you coerce to bool the output from New-Item you would get true. Most objects, when coerced to bool are true there are some exceptions of course.

    [bool] (New-Item -Type Directory -Path foo) # True
    

    And since, as explained before, Move-Item produces no output, when coerced it will give you false:

    [bool] (Move-Item -Path foo -Destination bar) # False
    

    And from there it's a simple comparison that will result into false:

    $true -and $false
    

    If you were using -PassThru and the operation succeeded then the comparison would've been true:

    (New-Item -Type Directory -Path foo) -and (Move-Item -Path foo -Destination bar -PassThru)
    

    Regarding the last update to the question, pipeline chain operators && and || exist in PowerShell 7, however these are usually used for external commands not for cmdlets. I wouldn't consider the example above using (cmdlet) -and (cmdlet) closer either.

    # Is valid in PowerShell 7
    New-Item -Type Directory -Path foo && Move-Item -Path foo -Destination bar
    

    Probably using -ErrorAction common parameter or $ErrorActionPreference set to Stop, then using pipelines could be the closest to &&. When the preference is Stop, the execution of a script, unless handled by a try / catch, ends immediately if there is an error and in turn the upstream command in pipeline never runs.

    # Move-Item never runs if New-Item fails due to the action preference
    New-Item -Type Directory -Path foo -ErrorAction Stop | Move-Item -Destination bar