Search code examples
powershellcopy-item

I am seeing the empty source directory being created in the destination folder along with the file while using Copy-item command in Powershell


$InputFile = "C:\InfoWorkflows.txt"

$fileText = Get-Content $InputFile

foreach ($LineText in $fileText){
    echo "LineText is $LineText"
    $containsWord = $LineText | %{$_ -match "test_control.xml"}
    if($containsWord -eq $false)
    {
        $SplitText = $LineText -split' '
        $Change = $SplitText[0]
        $fileName = $SplitText[1]
        echo "fileName is $fileName"
        echo "Copy-Item -Path C:\mb\INFO\$fileName -Destination C:\BackOrder\INFOT"
    }
}

In the destination folder C:\BackOrder\INFOT, I am able to see the files other than "test_Control.xml" on executing the PS which are mentioned in the inputFile and also a blank Folder (INFO) is being created from Source Path for which I never provided any instruction.Can someone look into it and help me?


Solution

  • The code you have does not check for the existance of the output folder 'C:\BackOrder\INFOT', nor does it check if the 'C:\mb\INFO\$fileName' exists. Other than that, I don't see why you are stringyfying the Copy-Item cmdlet..

    Another thing is that you use the regex -match operator on a filename containing a period (.) character without escaping it. In Regex, the dot has a special meaning, namely 'any character.'

    The code below uses the String object method .Contains to filter for strings that do not contain "test_control.xml" in a Where-Object{} clause. In the code comment you can read how to use [Regex]::Escape() if you do want to keep using -match.

    $InputFile = 'C:\InfoWorkflows.txt'
    $OutputDir = 'C:\BackOrder\INFOT'
    
    # test if output folder exists and if not create it first
    if (!(Test-Path -Path $OutputDir -PathType Container)) {
        Write-Host "Creating folder $OutputDir"
        $null = New-Item -Path $OutputDir -ItemType Directory
    }
    # read the input file as string array and filter the lines that do not contain "test_control.xml")
    # if you want to do that with the regex -match operator, you should escape it first:
    #   [Regex]::Escape("test_control.xml")  --> "test_control\.xml"
    $fileText  = Get-Content $InputFile | Where-Object { !$_.Contains("test_control.xml") } | ForEach-Object {
        $fileName = ($_ -split ' ')[1]
        Write-Host "FileName is $fileName"
        # combine the path and file name for the file to copy
        $sourceFile = Join-Path -Path 'C:\mb\INFO' -ChildPath $fileName
        if (Test-Path -Path $sourceFile -PathType Leaf) {
            Copy-Item -Path $sourceFile -Destination $OutputDir
        }
        else {
            Write-Warning "File '$sourceFile' could not be found."
        }
    }
    

    Hope that helps