Positional parameter cannot be found error in powershell - powershell

I am trying to append the date to a file name in my Powershell script but keep getting the following error (my code is below the error). Any help/direction would be greatly appreciated. Thank you.
Set-Content : A positional parameter cannot be found that accepts
argument '$null'.
At P:\CoverageVerifier\CombineTextFiles.ps1:8 char:50
+ ... thTrailer | Set-Content "${path}\\" + ${$dateStr} + "_CoverageVerifi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Content], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SetContentCommand
Here is my powershell code:
$path = "\\xx\\apps\\CoverageVerifier\\"
$pathHeader = "\\xx\\apps\\CoverageVerifier\\Header.txt"
$pathData = "\\xx\\apps\\CoverageVerifier\\Data.txt"
$pathTrailer = "\\xx\\apps\\CoverageVerifier\\Trailer.txt"
$date = Get-Date
$dateStr = $date.ToString("yyyyMMdd")
#Write-Output $dateStr
Get-Content $pathHeader,$pathData,$pathTrailer | Set-Content "${path}\\cvgver." + ${dateStr} + ".0101"

The first positional parameter of the Set-Content cmdlet is the -Path parameter.
Because of the way you define the paths for the files, it is bound to have problems with that.
As I understand, these are UNC paths, so try this instead:
# for LOCAL paths
# Set the driveletter to the actual drive you are using. For demo I'm using 'X:\'
# $path = 'X:\apps\CoverageVerifier'
# for UNC paths
# change 'servername' to your actual servers name
$path = '\\servername\apps\CoverageVerifier'
$pathHeader = Join-Path -Path $path -ChildPath 'Header.txt'
$pathData = Join-Path -Path $path -ChildPath 'Data.txt'
$pathTrailer = Join-Path -Path $path -ChildPath 'Trailer.txt'
$dateStr = (Get-Date).ToString("yyyyMMdd")
$outFile = Join-Path -Path $path -ChildPath ($dateStr + "_TestVerifier.txt")
Get-Content $pathHeader, $pathData, $pathTrailer | Set-Content $outFile
As you can see, I'm using the Join-Path cmdlet a lot to make sure my file paths get concatenated correctly.

Why don't you use the format operator and Join-Path?
Edit even with only one format
$path = "\\xx\apps\CoverageVerifier"
$pathHeader = Join-Path $path "Header.txt"
$pathData = Join-Path $path "Data.txt"
$pathTrailer = Join-Path $path "Trailer.txt"
Get-Content $pathHeader,$pathData,$pathTrailer |
Set-Content (Join-Path $path ("{0:yyyyMMdd}_TestVerifier.txt" -f (Get-Date))

you use set-content to modify the content of a file, not the filename:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-content?view=powershell-6

Related

Export Variable contents to file

I have contents in a variable from GitHub and I want to export then to file automatically created o my local machine
I have tried to use
$FileContent | Out-File ('C:\Devjobs\clonefolder' + '\' + $repo.name + '\' + $srccontent.name)
It gives the error
Out-File : Could not find a part of the path 'C:\Devjobs\clonefolder\bct-common-devcomm-codegen-messages\BCT.Common.DevComm.CodeGen.Messages.sln'.
At line:1 char:18
+ ... lnContent | Out-File ('C:\Devjobs\clonefolder' + '\' + $repo.name + ' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
As stackprotector already commented, the error shows DirectoryNotFoundException, which means you are trying to create a file in a directory that does not yet exist.
To avoid that, first create the path for the output file, then create the file.
$pathOut = Join-Path -Path 'C:\Devjobs\clonefolder' -ChildPath $repo.name
# create the folder path if it does not exist already
$null = New-Item -Path $pathOut -ItemType Directory -Force
# now write the file
$FileContent | Set-Content -Path (Join-Path -Path $pathOut -ChildPath $srccontent.name)
By using the -Force switch on New-Item you will either create the directory, OR have a DirectoryInfo object returned if the folder already existed.
In this case, we have no further need for that object, so we discard it with $null =.
Beware that this only works like that on the file system, if you would do the same on a registry key, you wil lose all content of the existing key!
Note: I use Set-Content rather than Out-File because on PowerShell versions up to and including 5.1, Out-File without using the -Encoding parameter will write the file in Unicode (UTF16-LE) encoding which may or may not be what you expect.
Following your comment:
foreach ($srccontent in $srccontents) {
if (<cond>) {
$slnContent = <rest>
$NewslnContent = "content"
$pathOut = Join-Path -Path 'C:\Devjobs\clonefolder' -ChildPath $repo.name
# first create the folder path if it does not exist already
$null = New-Item -Path $pathOut -ItemType Directory -Force
# now write the file
$NewslnContent | Set-Content -Path (Join-Path -Path $pathOut -ChildPath $srccontent.name)
}
}
Instead of string concatenation you may want to try Join-Path for cross-platform. That being said, if you are on a Windows machine this is not likely to be your issue.
You may want to use Test-Path to verify if the path and the file exists already.
$path = 'C:' |
Join-Path -ChildPath 'Devjobs' |
Join-Path -ChildPath 'clonefolder' |
Join-Path -ChildPath $repo.name
$filepath = $path | Join-Path -ChildPath $srccontent.name
If (-Not (Test-Path $path)) {
New-Item -Type Directory -Path $path
}
If (-Not (Test-Path $filepath)) {
Remove-Item -Path $filepath
}
$FileContent | Out-File $filepath

PowerShell copy-item

I am trying to copy latest 30days files to the folder by this code:
$month = (get-date).AddDays(-30).ToString("yyyMM")
$lastmonthfiles = Write-Host (-join('DCP_', $month,"*.csv"))
Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles)) -Destination C:\DC+\History\Backup
but I am having a problem in path in copy-item instruction, which is
Copy-Item : A positional parameter cannot be found that accepts argument 'C:\DC+\History\'.
At line:5 char:1
+ Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
I am new in PowerShell, and programming so, I could not understand, how can I update and achieve a goal.
Try this:
$Source = Get-Item "C:\Games"
$Destination = "E:\Backup"
$LogFile = "C:\Copy-LogFile.txt"
Copy-Item -Path $( $Source | Where LastWriteTime -LE (Get-Date).AddDays(-30) ) -Destination $Destination -Recurse -PassThru |
Out-File $LogFile -Force
This takes care of your copy function and generates an output log.
Sorry, but your code makes no sense to me...
If it is your aim to copy files to a subfolder in a backup path, try this:
# get the date to use as subfolder to copy to and also to filter the last 30 days files
$refDate = (Get-Date).AddDays(-30).Date # .Date sets it to midnight
# set this variable to the folder where the csv are to be found
$sourceFolder = 'X:\Path\To\Where\The\Files\Are'
# create a destination path to copy to (just a string)
$destination = Join-Path -Path 'C:\DC+\History\Backup' -ChildPath ($refDate.ToString("yyyMM"))
# create this destination folder
$null = New-Item -Path $destination -ItemType Directory -Force
# get the files and copy them to the destination folder
Get-ChildItem -Path $sourceFolder -Filter '*.csv' -File | # filter on CSV fies only
Where-Object { $_.LastWriteTime -ge $refDate } | # filter on date 'last 30 days'
Copy-Item -Destination $destination -Force

Powershell script - Replace FilePath for all the URIs given in a Text file

I'm new to Power-Shell.
Given a text file with multiple file paths each separated by a New Line, I'm trying to replace the file path of each of these with a new path for the same file.
Example:
Input file :
C:\Project\SharedLib\Shared\log4net.dll
C:\Project\SharedLib\Shared\Aspose.dll
C:\Dependency\SL\UnStable\Crystal.dll
Output file :
\\ServerName\websites$\Stable\Release\log4net.dll
\\ServerName\websites$\Stable\Release\Aspone.dll
\\ServerName\websites$\Stable\Release\Crystal.dll
My attempt:
Get-ChildItem "*.txt" -Filter *.txt |
Foreach-Object {
foreach($line in Get-Content $_) {
$currentPath = [System.IO.Path]::GetDirectoryName($line)
($line) -replace $currentPath, '\\ServerName\websites$\Stable\Release\' | Set-Content $line
}
}
This is erring on the replace line.
this uses Split-Path to get the file name. then it uses Join-Path to build the new full path. [grin]
$SourceFile = "$env:TEMP\Reddy-In.txt"
$DestFile = "$env:TEMP\Reddy-Out.txt"
# create a file to work with
# remove this section when ready to use your own data
#'
C:\Project\SharedLib\Shared\log4net.dll
C:\Project\SharedLib\Shared\Aspose.dll
C:\Dependency\SL\UnStable\Crystal.dll
'# | Set-Content -LiteralPath $SourceFile
$Prefix = '\\ServerName\websites$\Stable\Release'
$InStuff = Get-Content -LiteralPath $SourceFile
$Results = foreach ($IS_Item in $InStuff)
{
$FileName = Split-Path -Path $IS_Item -Leaf
Join-Path -Path $Prefix -ChildPath $FileName
}
# display on screen
$Results
# send to a text file
$Results |
Set-Content -LiteralPath $DestFile
screen output ...
\\ServerName\websites$\Stable\Release\log4net.dll
\\ServerName\websites$\Stable\Release\Aspose.dll
\\ServerName\websites$\Stable\Release\Crystal.dll
text file content ...
\\ServerName\websites$\Stable\Release\log4net.dll
\\ServerName\websites$\Stable\Release\Aspose.dll
\\ServerName\websites$\Stable\Release\Crystal.dll
The error message I was getting was
The regular expression pattern C:\Project\SharedLib\Shared is not valid.
At C:\temp\StackOverflow.ps1:6 char:9
+ ($line) -replace $currentPath, '\\ServerName\websites$\Stable ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (C:\Project\SharedLib\Shared:String) [], RuntimeException
+ FullyQualifiedErrorId : InvalidRegularExpression
This tells me that the string C:\Project\SharedLib is being treated as a RegEx pattern- and we need to escape the operators. (That's why you'll often see backslashes doubled up- they are escaped.)
No need to remember what they are all- you can use [regex]::escape($currentPath) to do it for you.
Get-ChildItem "*.txt" -Filter *.txt |
Foreach-Object {
foreach($line in Get-Content $_) {
$currentPath = [System.IO.Path]::GetDirectoryName($line)
($line) -replace [regex]::escape($currentPath), '\\ServerName\websites$\Stable\Release\' | Set-Content $line
}
}

Test-Path - Illegal characters in path when using a variable

I m fairly new to PowerShell and I apologize in advance if this is a dumb question.
I am trying to construct a new destination/filename where I take the old filename and increment its prefix with +1
$destination = Split-Path -Path 'C:\Users\tom\Desktop\test\0_InstalledPrograms.log'
$file = split-path "C:\Users\tom\Desktop\test\0_InstalledPrograms.log" -Leaf
$array = $file -split '_'
$prefix = $array[0] + 1
$suffix = $array[1]
$newFile = $prefix + '_' + $suffix
$newFile = Out-String -InputObject $newFile
$destination = $destination + '\' + $newFile
Test-Path $destination
Test-Path : Illegal characters in path.
At C:\Users\tom\Desktop\incrementFileName.ps1:18 char:1
+ Test-Path $destination
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (C:\Users\lgranc...dPrograms.log
:String) [Test-Path], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.TestPathCommand
False
This statement:
$newFile = Out-String -InputObject $newFile
adds a new line (CR+LF) to the string, and is completely unnecessary ($newFile is already a string).
Remove that line and it'll work :)
You can do it easily as follows:
$file = "C:\Users\tom\Desktop\test\0_InstalledPrograms.log"
$splittedName = (Split-Path $file -leaf).split('_')
$newFileName = [string]([int]$splittedName[0] + 1) +'_'+ $splittedName[1]
Move-Item -Path $file -Destination (Join-Path (Split-path $file) -ChildPath $newFileName)

Move-Item to correct Destination

The Script:
Creates a list of folders based on the filenames in the scripts root directory, each folder breaks down the name by "Year/Month/Day"
Moves each file to the designated folder
Error Message:
CategoryInfo : ObjectNotFound:
(S:\Data\TECHNOL...59_20180108.txt:String)
[Move-Item], ItemNotFoundException FullyQualifiedErrorId :
PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
My Issue
The files will not move to the correct endpath
#Create Directory
Set-StrictMode -Version 2
$rootPath = split-path -parent $MyInvocation.MyCommand.Definition
cd $rootPath
$FileNameArray = Get-ChildItem -Filter "*.txt"
$FileNameArray = $FileNameArray -replace "....$"
$FileNameArray = $FileNameArray -replace "^59_"
Foreach($f in $FileNameArray)
{
$Year = $f -replace "^\d{0}|\d{4}$" #"....$"
$Month = $f -replace "^\d{4}|\d{2}$"
$Month = $Month | sort -Unique
$Day = $f -replace "^\d{6}|\d{0}$"
#Loop 2a
Foreach($m1 in $Month){
#Loop 2a-a
Foreach($d1 in $Day){
Move-Item -Path ($rootPath + '\59_' + $file + '.txt')
-Destination ($rootPath + '\' + $Year + '\' + $m1 + '\' + $d1)
}
}
}
Apologies for the spaghetti code & simple question, I am new to both Computer Science and PowerShell.
The following script has two security features:
The MD command has a trailing -confirm you have to answer
The Move-Item has a -WhatIf which shows what would be done without the Parameter
If the script works OK, remove them both.
## Q:\Test\2018\05\03\SO_50158185.ps1
Set-StrictMode -Version 2
$rootPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
cd $rootPath
Get-ChildItem "59_20[0-9][0-9][0-1][0-9][0-3][0-9].txt" |
Where-Object {$_.BaseName -Match '59_(?<year>\d{4})(?<Month>\d{2})(?<Day>\d{2})'}|
ForEach-Object {
$DestDir = Join-Path $rootPath ("{0}\{1}\{2}" -f $Matches.Year,$Matches.Month,$Matches.Day)
If (!(Test-Path $DestDir)) {MD $DestDir -Confirm| Out-Null}
$_ | Move-Item -Destination $DestDir -WhatIf
}
Figured it out guys! Just needed to change $file to $f. Thanks for all the help.