Home>


In a Powershell script that searches for a file with a certain name and changes a specific keyword in that file, as a backup function for the file before the change, it is used as an alias to the same directory where the original file is located (with the same file name). (Add date and time information) The copy creation function has not been realized, and I search the web and look at the book, but since I was writing a Powershell script for the first time, I could not find a solution The I would appreciate any advice. Thank you in advance.

Error:
Copy-Item: The given path's format is not supported.
At C: \ Users \ Desktop \ PS_Folder \ change_connstr.ps1: 38 char: 17
+ ... Copy-Item -Path $fPath'\'$targetFile -Destination $fPath'...
+~~~~~~< del>~~~~~~~
+ CategoryInfo: NotSpecified: (:) [Copy-Item], NotSupportedException
+ FullyQualifiedErrorId: System.NotSupportedException, Microsoft.PowerShell.Commands.CopyItemCommand

The pre-correction script for the part to be backed up is as follows.

# Because there are files with the same name in multiple subdirectories, get them recursively
$web_configfiles = Get-ChildItem $homeDir -recurse -include $targetFile
#Specification to determine whether to get backup
    $backUp = Read-Host "Do You Want to Take Backups of $targetFile? Please enter Y or N"
    if ($backUp -eq "Y") {
        echo "--Start Backuping $targetFile--`r`n"
        # Get only the directory path where the file was found below
        $dir_paths = ($web_configfiles) .DirectoryName
Get one file at a time in # loop
        foreach ($bkFile in $web_configfiles) {
Get the target directory path one by one in # loop
            foreach ($fPath in $dir_paths) {
#: #The path and file to be copied are not passed successfully, resulting in the above error
                Copy-Item -Path $fPath '\' $bkFile -Destination $fPath '\' $bkFile '_' $date $fPath '\ web.config _' $date
                echo "Backup was success to make in: $fPath"
            }
        }
    }
    elseif ($backUp -eq "N") {
        echo "--User didn't choose to take backups--`r`n"
    }
    else {
        echo "--Please enter Y or N--"
        exit

Regarding what Satocha has pointed out:

The result of echoing web_configfiles is output for the number of hit files as follows. This time, 9 files called web.config are hit in the search.

Directory: C: \ Users \ Desktop \ PS_Folder \ A

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a ---- 9/1/2018 8:54 PM 5308 web.config


$web_configfiles | foreach-object {
            $filePath = $_. fullname #Get the full path of the file as a string
            #echo $filePath
            $parent = split-path $filePath #parent directory
            #echo $parent
            $fileBase = [io.path] :: getFileNameWithoutExtension ($filePath) #File name without extension
            #echo $fileBase
            $ext = [io.path] :: getExtension ($filePath) #Extension (including.)
            #echo $fileBase $ext
            #After that, assemble the new pass appropriately and copy it
            $sourcePath = Join-Path $parent $fileBase $ext
            $destPath = Join-Path $parent $fileBase $ext $date
            echo $sourcePath
            echo $destPath
            Copy-Item -Path $sourcePath -Destination $destPath
        }


The path and file name of the target directory of the copy source and copy destination are intended, but an error occurs.

echo $sourcePath
C: \ Users \ Desktop \ PS_Folder \ CC \ A \ web.config
echo $destPath
C: \ Users \ Desktop \ PS_Folder \ CC \ A \ web.config-20180902-11: 18: 47

Copy-Item: The given path's format is not supported.
At C: \ Users \ Desktop \ PS_Folder \ change_connstr.ps1: 51 char: 13
+ Copy-Item -Path $sourcePath -Destination $destPath
+~~~~~~< del>~~~~
+ CategoryInfo: NotSpecified: (:) [Copy-Item], NotSupportedException
+ FullyQualifiedErrorId: System.NotSupportedException, Microsoft.PowerShell.Commands.CopyItemCommand

Regarding points pointed out by satocha, part 2:

As satocha pointed out, the format of the date variable was a problem.
I changed it to the following and the script gave the expected result!

$date = Get-Date -Format"-yyyyMMdd-HH-mm-ss"

However, True was returned even if it contained a colon.
PS C: \ Users \ Desktop \ PS_Folder>test-path -isvalid"C: \ Users \ Desktop \ PS_Folder \ CC \ A \ web.config-20180902-11: 18: 47"
True

I think it's a dirty code that still has much room for improvement, but the modified full code is as follows.

$date = Get-Date -Format "-yyyyMMdd-HH-mm-ss"
$homeDir = 'C: \ Users \ Desktop \ PS_Folder'
$conStrFrom = 'Server1'
$conStrTo = 'Server2'
$targetFile = 'web.config'
Set-Location $homeDir
function Get-ScriptPath {
    Split-Path $MyInvocation.ScriptName
}
$CntReplaced = 0
if ((Get-ScriptPath) -eq $homeDir) {
    echo "The Path is correct: $homeDir"
    echo "` r`n "
    }
else {
    echo "--Script is not in the correct path !!-"
    exit
}
    $web_configfiles = Get-ChildItem $homeDir -recurse -include $targetFile
    $filesCnt = ($web_configfiles) .Count
    echo ("There are $filesCnt` "$targetFile`" Files`r`n ")
    $backUp = Read-Host "Do You Want to Take Backups of $targetFile? Please enter Y or N"
    if ($backUp -eq "Y") {
        echo "--Start Backuping $targetFile--`r`n"
        $web_configfiles | foreach-object {
            $filePath = $_. fullname
            $parent = split-path $filePath
            $fileBase = [io.path] :: getFileNameWithoutExtension ($filePath)
            $ext = [io.path] :: getExtension ($filePath)
            $sourcePath = Join-Path $parent $fileBase $ext
            $destPath = Join-Path $parent $fileBase $ext $date
            Copy-Item -Path $sourcePath -Destination $destPath
            echo "Backup was successful to create in: $parent"
        }
    }
    elseif ($backUp -eq "N") {
        echo "--User didn't choose to take backups--`r`n"
    }
    else {
        echo "--Please enter Y or N--"
        exit
    }
    if ($web_configfiles) {
        foreach ($file in $web_configfiles) {
            $cnt = (Get-Content $file | Select-String $conStrFrom) .Count
            $fname = Split-Path $file -Leaf
            echo ("$fname contains Target text in` "$cnt`" location ")
            if ($cnt -gt 0) {
                (Get-Content $file) | Foreach-Object {$_ -creplace $conStrFrom, $conStrTo} | Set-Content $file
                $CntReplaced = $CntReplaced + 1
            }
            else {
                echo ("--The File doesn't contain Target Text--")
            }
        }
    }
echo `r`n
echo "` "$CntReplaced`" $fname files of text `" $conStrFrom` "were replaced to` "$conStrTo`" "
  • Answer # 1

    If you output each variable with echo instead of Copy-Item in the line of Copy-Item, you should know what is wrong.
    Maybe the file name is not taken.

    The problem is

    $dir_paths = ($web_configfiles) .DirectoryName


    And

    The value of $dir_paths is null when there are multiple hits in the search. This is because $web_configfiles (ie Get-ChildItem output) is a FileInfo type (or DirectoryInfo type) if only one search hits, an Object [] array for multiple searches, or $null if not found.
    Since there is no property called DirectoryName in the array, the value of $dir_paths is $null when multiple items are found.

    It seems that the whole directory analysis is quite difficult.
    It is easy to get the full path of the found file as a string and disassemble it with the split-path cmdlet or system.io.path method.

    $FoundFiles = Get-ChildItem Honyara
    $FoundFiles | foreach-object {
        $filepath = $_. fullname # Get full file path as a string
        $parent = split-path $filepath #parent directory
        $fileBase = [io.path] :: getFileNameWithoutExtension ($filepath) #File name without extension
        $ext = [io.path] :: getExtension ($filepath) #Extension (including.)
        #After that, assemble the new pass appropriately and copy it
    }

  • Answer # 2

    The error message is as follows.
    Contains characters that should not be used as file names.

    test-path -isvalid "C: \ Users \ Desktop \ PS_Folder \ CC \ A \ web.config-20180902-11: 18: 47"


    Should return false.
    For a complete list of characters that should not be used,

    [io.path] :: GetInvalidFileNameChars ()


    Can be obtained at

    This time, the colon between the times is bad (because the colon is a letter indicating the drive name etc.).
    I'm preparing the variable $date somewhere,
    For example, if FileInfo is included in $file

    $datestr = $file.lastWriteTime.toString () -replace "/", "" -replace ":", "_" -replace "", "-"


    If you do, you can get a time string without problems. As a precaution, check with test-path -isvalid above.