I created this script that works perfectly in ISE but fails with the below output when porting it into my command line tool. Here is the script.
$source_folder = $args[0];
$destination_folder = $args[1];
$DateFormat = $arg[2];
Get-ChildItem -Path $source_folder -File|
Move-Item -Destination $destination_folder + ((Get-Date -Format $DateFormat).ToString() + $_.BaseName + $_.Extension)
It fails with the below error
Cannot index into a null array.
At C:\ProgramData\CopyFileAppendDate.ps1:3 char:1
+ $DateFormat = $arg[2];
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Move-Item : A positional parameter cannot be found that accepts argument '5/13/2024 5:11:58 PM'.
At C:\ProgramData\CopyFileAppendDate.ps1:5 char:5
+ Move-Item -Destination $destination_folder + ((Get-Date -Format ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Move-Item], ParameterBindingException `
+ FullyQualifiedError`
`
Id : PositionalParameterNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
I am thinking it has something to do with my Get-Date because in the error log it seems to be generating the full date with colons which will obviously not work in a file name. Hard-coding the parameters in the script, as so, works in ISE:
$source_folder = "\\server\folder\another folder\*.*"
$destination_folder = "E:\Drive\folder\another folder\"
$DateFormat = "MMddyyyy"
Leaving the parameters as so, and then entering the parameters on the command line as arguments does not work:
This is what's on the command line:
"\\server\folder\another folder\*.*" "E:\folder\another folder\" "MMddyyyy"
And this is the first 3 lines of the script when trying to run on command line:
$source_folder = $args[0];
$destination_folder = $args[1];
$DateFormat = $arg[2];
# Using this the shell autosuggest the names, making it much easier to read and remember
[CmdletBinding()]
param(
[Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
[string] $source_folder,
[Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
[string] $destination_folder ,
[Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
[string] $DateFormat,
[Parameter(Mandatory, Position = 3, ValueFromPipelineByPropertyName)]
[switch] $Force
)
# test if the destination folder does exists
# if not, creates it. Assigning to $null to hide the output
if (-not ($DestinationDirectory = Resolve-Path -Path $destination_folder -ErrorAction SilentlyContinue )) {
$DestinationDirectory = New-Item -ItemType Directory -Path $destination_folder
}
# Get the date as formatted
# Move this inside the ForEach if there is a chance you run this through a day-change
# and you need the date of the time of the move
$Date = Get-Date -Format $DateFormat
Get-ChildItem -Path $source_folder -File |
# Using Foreach-Object because a number of operations are needed to be performed to get the final destination filename
# it might be a bit less efficient but it makes the code much more readable
ForEach-Object {
# create the new name
# the property .Name already contains the Extension
# for sake of readibility and simplicity I'm using a hardcoded value for the separator
# You can add it as another argument or place it in the date format string.
$DestinationName = Join-String -InputObject $Date, $_.Name -Separator '-'
# using Join-Path makes sure there is no mess with the path
$FinalDestination = Join-Path -Path $DestinationDirectory -ChildPath $DestinationName
# Move the item, using the .FullName property to avoid conflicts
Move-Item -Path $_.FullName -Destination $FinalDestination -Force:$Force
}