PowerShell/test/powershell/Modules/Microsoft.PowerShell.Management/Copy-Item.Tests.ps1

864 lines
35 KiB
PowerShell

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Validate Copy-Item locally" -Tags "CI" {
It "Copy-Item has non-terminating error if destination is in use" -Skip:(!$IsWindows) {
Copy-Item -Path $env:windir\system32\cmd.exe -Destination TestDrive:\
$cmd = Start-Process -FilePath TestDrive:\cmd.exe -PassThru
try {
{ Copy-Item -Path $env:windir\system32\cmd.exe -Destination TestDrive:\ -ErrorAction SilentlyContinue } | Should -Not -Throw
}
finally {
$cmd | Stop-Process
}
}
}
# This is a Pester test suite to validate Copy-Item remotely using a remote session.
# If PS Remoting is not available, do not run the suite.
function ShouldRun
{
if ( $IsCoreCLR ) { return $false }
$result = Invoke-Command -ComputerName . -ScriptBlock {1} -ErrorAction SilentlyContinue
return ($result -eq 1)
}
if (-not (ShouldRun))
{
Write-Host "PS Remoting is not available, skipping tests..." -ForegroundColor Cyan
return
}
Describe "Validate Copy-Item Remotely" -Tags "CI" {
# Validate a copy item operation.
# $filePath is the source file path
#
function ValidateCopyItemOperation
{
param ([string]$filePath, [string]$destination)
if (-not $destination)
{
$copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory")
}
else
{
$fileName = Split-Path $filePath -Leaf
$copiedFilePath = Join-Path $destination $fileName
}
$copiedFilePath | Should -Exist
# Validate file attributes
$originalFile = Get-Item $filePath -Force
$newFile = Get-Item $copiedFilePath -Force
# Validate file Length
$newFile.Length | Should -Be $originalFile.Length
# Validate LastWriteTime
$newFile.LastWriteTime | Should -Be $originalFile.LastWriteTime
$newFile.LastWriteTimeUtc | Should -Be $originalFile.LastWriteTimeUtc
# Validate Attributes
$newFile.Attributes.value__ | Should -Be $originalFile.Attributes.value__
}
# Validate a copy item operation.
# $filePath is the source file path
#
function ValidateCopyItemOperationForAlternateDataStream
{
param ([string]$filePath, $streamName, $expectedStreamContent)
$copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory")
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $filePath).Length
# Validate the stream
$actualStreamContent = Get-Content -Path $copiedFilePath -Stream $streamName -ErrorAction SilentlyContinue
$actualStreamContent | Should -Match $expectedStreamContent
}
BeforeAll {
$s = New-PSSession -ComputerName . -ErrorAction SilentlyContinue
if (-not $s)
{
throw "Failed to create PSSession for remote copy operations."
}
$destinationFolderName = "DestinationDirectory"
$sourceFolderName = "SourceDirectory"
$testDirectory = Join-Path -Path "TestDrive:" -ChildPath "copyItemRemotely"
$destinationDirectory = Join-Path -Path $testDirectory -ChildPath $destinationFolderName
$sourceDirectory = Join-Path -Path $testDirectory -ChildPath $sourceFolderName
# Creates one txt file
#
function CreateTestFile
{
param ([switch]$setReadOnlyAttribute = $false, [switch]$emptyFile = $false)
# Create the test directory.
New-Item -Path $sourceDirectory -Force -ItemType Directory | Out-Null
# Create the file.
$filePath = Join-Path -Path $sourceDirectory -ChildPath "testfileone.txt"
if (-not $emptyFile)
{
"File test content" | Out-File -FilePath $filePath -Force
}
else
{
"" | Out-File -FilePath $filePath -Force
}
if (-not (Test-Path $filePath))
{
throw "Failed to create test file $filePath."
}
if ($setReadOnlyAttribute)
{
Set-ItemProperty -Path $filePath -Name IsReadOnly -Value $true -Force
}
return (Get-Item $filePath).FullName
}
# Create a set of directories and files with the following structure:
# .\copyItemRemotely\SourceDirectory\A\a.txt
# .\copyItemRemotely\SourceDirectory\A\a2.txt
# .\copyItemRemotely\SourceDirectory\rootFile.txt
# .\copyItemRemotely\SourceDirectory\B\b.txt
# .\copyItemRemotely\SourceDirectory\C\D\d.txt
#
function CreateTestDirectory
{
param ([switch]$setReadOnlyAttribute = $false)
$directoriesToCreate = @()
$directoriesToCreate += "A"
$directoriesToCreate += "B"
$directoriesToCreate += "C\D"
$filesToCreate = @()
$filesToCreate += "rootFile.txt"
$filesToCreate += "A\a.txt"
$filesToCreate += "A\a2.txt"
$filesToCreate += "B\b.txt"
$filesToCreate += "C\D\d.txt"
# Create the directories.
foreach ($directory in $directoriesToCreate)
{
$directoryPath = Join-Path -Path $sourceDirectory -ChildPath $directory
New-Item -Path $directoryPath -Force -ItemType Directory | Out-Null
}
$result = @{
SourceDirectory = (Get-Item $sourceDirectory).FullName
Files = @()
}
# Create the files.
foreach ($file in $filesToCreate)
{
$filePath = Join-Path -Path $sourceDirectory -ChildPath $file
$file + "`r`n File test content" | Out-File -FilePath $filePath -Force
if (-not (Test-Path -Path $filePath))
{
throw "Failed to create test file $filePath."
}
if ($setReadOnlyAttribute)
{
Set-ItemProperty -Path $filePath -Name IsReadOnly -Value $true -Force
}
$result.Files += (Get-Item -Path $filePath).FullName
}
return $result
}
function GenerateTestAssembly
{
$assemblyPath = Join-Path -Path $env:TEMP -ChildPath TestModule
$outputPath = Join-Path -Path $assemblyPath -ChildPath TestModule.dll
if (-not (Test-Path -Path $assemblyPath))
{
New-Item -Path $assemblyPath -Force -ItemType Directory | Out-Null
}
if (-not (Test-Path -Path $outputPath))
{
$code = @"
namespace TestModule
{
using System;
using System.Management.Automation;
[Cmdlet(VerbsCommon.Get, "TestModule")]
public class TestSameCmdlets : PSCmdlet
{
protected override void ProcessRecord()
{
WriteObject("TestModule");
}
}
}
"@
Add-Type -TypeDefinition $code -OutputAssembly $outputPath
}
$result = @{
ModuleName = "TestModule"
Path = (Get-Item $outputPath).FullName
}
return $result
}
function GetDestinationFolderPath
{
return (Get-Item -Path $destinationDirectory).FullName
}
}
AfterAll {
Remove-PSSession -Name $s.Name -ErrorAction SilentlyContinue
}
BeforeEach {
<# Ensure we start with an empty test directory. Here is the file structure
$destinationFolderName = "DestinationDirectory"
$sourceFolderName = "SourceDirectory"
$testDirectory = Join-Path "TestDrive:" "copyItemRemotely"
$destinationDirectory = Join-Path $testDirectory $destinationFolderName
$sourceDirectory = Join-Path $testDirectory $sourceFolderName
#>
if (Test-Path -Path $testDirectory)
{
Remove-Item -Path $testDirectory -Force -ErrorAction SilentlyContinue -Recurse
}
# Create testDirectory, and destinationDirectory
New-Item -Path $testDirectory -ItemType Directory -Force | Out-Null
New-Item -Path $destinationDirectory -ItemType Directory -Force | Out-Null
}
Context "Validate Copy-Item Locally." {
It "Copy-Item -Path $filePath -Destination $destinationFolderPath" {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $filePath -Destination $destinationFolderPath
ValidateCopyItemOperation -filePath $filePath
}
It "Copy-Item -Path $($testObject.SourceDirectory) -Destination $destinationFolderPath -Recurse" {
$testObject = CreateTestDirectory
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $testObject.SourceDirectory -Destination $destinationFolderPath -Recurse
foreach ($file in $testObject.Files)
{
$copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory")
$copiedFilePath | Should -Exist
}
}
}
Context "Validate Copy-Item to remote session." {
It "Copy one file to remote session." {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath
ValidateCopyItemOperation -filePath $filePath
}
It "Copy one read only file to remote session." {
$filePath = CreateTestFile -setReadOnlyAttribute
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -Force
ValidateCopyItemOperation -filePath $filePath
}
It "Copy-Item works for a read only file when '-Force' is not used." {
$filePath = CreateTestFile -setReadOnlyAttribute
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -Verbose
ValidateCopyItemOperation -filePath $filePath
}
It "Copy one folder to session Recursively" {
$testObject = CreateTestDirectory
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $testObject.SourceDirectory -ToSession $s -Destination $destinationFolderPath -Recurse
foreach ($file in $testObject.Files)
{
$copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory")
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
It "Copy folder with read only files to remote session recursively." {
$testObject = CreateTestDirectory -setReadOnlyAttribute
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $testObject.SourceDirectory -ToSession $s -Destination $destinationFolderPath -Recurse -Force
foreach ($file in $testObject.Files)
{
$copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory")
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
It "Copy one file to remote session fails when the remote directory does not exist." {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
$destinationFolderPath = Join-Path $destinationFolderPath "A\B\C\D\E"
$expectedFullyQualifiedErrorId = 'RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand'
{ Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -ErrorAction Stop } |
Should -Throw -ErrorId $expectedFullyQualifiedErrorId
}
It "Copy folder to remote session recursively works even if the target directory does not exist." {
$testObject = CreateTestDirectory -setReadOnlyAttribute
$destinationFolderPath = GetDestinationFolderPath
$destinationFolderPath = Join-Path $destinationFolderPath "FoderThatDoesNotExist"
Copy-Item -Path $testObject.SourceDirectory -ToSession $s -Destination $destinationFolderPath -Recurse -Force
foreach ($file in $testObject.Files)
{
$copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\FoderThatDoesNotExist")
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
It "Copy one empty file to remote session." {
$filePath = CreateTestFile -emptyFile
$destinationFolderPath = GetDestinationFolderPath
$copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory")
$copiedFilePath | Should -Not -Exist
Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $filePath).Length
}
It "Copy-Item to session supports alternate data streams." {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
$streamContent = "This content is hidden"
$streamName = "Hidden"
Set-Content -Path $filePath -Value $streamContent -Stream $streamName
Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -Verbose
ValidateCopyItemOperationForAlternateDataStream -filePath $filePath -streamName $streamName -expectedStreamContent $streamContent
}
}
Context "Validate Copy-Item from remote session." {
It "Copy one file from remote session." {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
$copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory")
$copiedFilePath | Should -Not -Exist
Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath
ValidateCopyItemOperation -filePath $filePath
}
It "Copy one empty file from remote session." {
$filePath = CreateTestFile -emptyFile
$destinationFolderPath = GetDestinationFolderPath
$copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory")
$copiedFilePath | Should -Not -Exist
Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath
ValidateCopyItemOperation -filePath $filePath
}
It "Copy folder from remote session recursively." {
$testObject = CreateTestDirectory
$destinationFolderPath = GetDestinationFolderPath
$files = @(Get-ChildItem $destinationFolderPath -Recurse -Force)
Copy-Item -Path $testObject.SourceDirectory -FromSession $s -Destination $destinationFolderPath -Recurse
foreach ($file in $testObject.Files)
{
$copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\SourceDirectory")
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
It "Copy one file from remote session fails when the target directory does not exist." {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
$destinationFolderPath = Join-Path $destinationFolderPath "A\B\C\D\E"
$expectedFullyQualifiedErrorId = 'CopyItemRemotelyIOError,Microsoft.PowerShell.Commands.CopyItemCommand'
{ Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath -ErrorAction Stop } |
Should -Throw -ErrorId $expectedFullyQualifiedErrorId
}
It "Copy folder from remote session recursively works even if the target directory does not exist." {
$testObject = CreateTestDirectory
$destinationFolderPath = GetDestinationFolderPath
$destinationFolderPath = Join-Path $destinationFolderPath "FoderThatDoesNotExist"
$files = @(Get-ChildItem $destinationFolderPath -Recurse -Force)
Copy-Item -Path $testObject.SourceDirectory -FromSession $s -Destination $destinationFolderPath -Recurse
foreach ($file in $testObject.Files)
{
$copiedFilePath = ([string]$file).Replace("SourceDirectory", "DestinationDirectory\FoderThatDoesNotExist")
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
It "Copy a read only file from a remote session." {
$filePath = CreateTestFile -setReadOnlyAttribute
$destinationFolderPath = GetDestinationFolderPath
$copiedFilePath = ([string]$filePath).Replace("SourceDirectory", "DestinationDirectory")
Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath -Force
ValidateCopyItemOperation -filePath $filePath
}
It "Copy-Item for a read only file works with no '-force' parameter." {
$filePath = CreateTestFile -setReadOnlyAttribute
$destinationFolderPath = GetDestinationFolderPath
Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath
ValidateCopyItemOperation -filePath $filePath
}
It "Copy-Item -FromSession works even when trying to copy an assembly that is currently being used by another process." {
$testAssembly = GenerateTestAssembly
$destinationFolderPath = GetDestinationFolderPath
Import-Module $testAssembly.Path -Force
try
{
Copy-Item -Path $testAssembly.Path -FromSession $s -Destination $destinationFolderPath
ValidateCopyItemOperation -filePath $testAssembly.Path
}
finally
{
Remove-Module $testAssembly.ModuleName -Force -ErrorAction SilentlyContinue
}
}
It "Copy-Item from session supports alternate data streams." {
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
$streamContent = "This content is hidden"
$streamName = "Hidden"
Set-Content -Path $filePath -Value $streamContent -Stream $streamName
Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath
ValidateCopyItemOperationForAlternateDataStream -filePath $filePath -streamName $streamName -expectedStreamContent $streamContent
}
It "Copy file to the same directory fails." {
$filePath = CreateTestFile
{ Copy-Item -Path $filePath -Destination $sourceDirectory -FromSession $s -ErrorAction Stop } | Should -Throw -ErrorId "System.IO.IOException,WriteException"
}
It "Copy directory with a -Destination parameter given as a file path fails." {
$filePath = CreateTestFile
$folderToCopy = GetDestinationFolderPath
{ Copy-Item -Path $folderToCopy -Destination $filePath -FromSession $s -ErrorAction Stop } | Should -Throw -ErrorId "CopyError,Microsoft.PowerShell.Commands.CopyItemCommand"
}
It "Copy-Item parameters -FromSession and -ToSession are mutually exclusive." {
try
{
$s1 = New-PSSession -ComputerName . -ErrorAction SilentlyContinue
$s1 | Should -Not -BeNullOrEmpty
$filePath = CreateTestFile
$destinationFolderPath = GetDestinationFolderPath
{ Copy-Item -Path $filePath -Destination $destinationFolderPath -FromSession $s -ToSession $s1 -ErrorAction Stop } | Should -Throw -ErrorId "InvalidInput,Microsoft.PowerShell.Commands.CopyItemCommand"
}
finally
{
Remove-PSSession -Session $s1 -ErrorAction SilentlyContinue
}
}
}
Context "Validate Copy-Item Remotely using wildcards" {
It "Copy-Item from session using wildcards." {
$testObject = CreateTestDirectory
$destinationFolderPath = GetDestinationFolderPath
$sourcePathWithWildcards = "$($testObject.SourceDirectory)\A\*.txt"
Copy-Item -Path $sourcePathWithWildcards -FromSession $s -Destination $destinationFolderPath -Force
$sourceFiles = @(Get-Item $sourcePathWithWildcards)
foreach ($file in $sourceFiles)
{
$copiedFilePath = Join-Path $destinationFolderPath (Split-Path $file -Leaf)
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
It "Copy-Item to session using wildcards." {
$testObject = CreateTestDirectory
$destinationFolderPath = GetDestinationFolderPath
$sourcePathWithWildcards = "$($testObject.SourceDirectory)\A\*.txt"
Copy-Item -Path $sourcePathWithWildcards -ToSession $s -Destination $destinationFolderPath -Force
$sourceFiles = @(Get-Item $sourcePathWithWildcards)
foreach ($file in $sourceFiles)
{
$copiedFilePath = Join-Path $destinationFolderPath (Split-Path $file -Leaf)
$copiedFilePath | Should -Exist
(Get-Item $copiedFilePath).Length | Should -Be (Get-Item $file).Length
}
}
}
Context "Validate FullyQualifiedErrorIds for remote source and destination paths." {
BeforeAll {
# Create test file.
$testFilePath = Join-Path "TestDrive:" "testfile.txt"
if (Test-Path $testFilePath)
{
Remove-Item $testFilePath -Force -ErrorAction SilentlyContinue
}
"File test content" | Out-File $testFilePath -Force
}
function Test-CopyItemError
{
param ($path, $destination, $expectedFullyQualifiedErrorId, $fromSession = $false)
if ($fromSession)
{
It "Copy-Item FromSession -Path '$path' throws $expectedFullyQualifiedErrorId" {
{ Copy-Item -Path $path -FromSession $s -Destination $destination -ErrorAction Stop } |
Should -Throw -ErrorId $expectedFullyQualifiedErrorId
}
}
else
{
It "Copy-Item ToSession -Destination '$path' throws $expectedFullyQualifiedErrorId" {
{ Copy-Item -Path $path -ToSession $s -Destination $destination -ErrorAction Stop } |
Should -Throw -ErrorId $expectedFullyQualifiedErrorId
}
}
}
$invalidSourcePathtestCases = @(
@{
Path = "HKLM:\SOFTWARE"
Destination = $env:SystemDrive
ExpectedFullyQualifiedErrorId = "NamedParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand"
FromSession = $true
}
@{
Path = ".\Source"
Destination = $env:SystemDrive
ExpectedFullyQualifiedErrorId = "RemotePathIsNotAbsolute,Microsoft.PowerShell.Commands.CopyItemCommand"
FromSession = $true
}
@{
Path = $env:SystemDrive + "\X\Y\Z"
Destination = $env:SystemDrive + "\A\B\C"
ExpectedFullyQualifiedErrorId = "RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand"
FromSession = $true
}
@{
Path = $null
Destination = $env:SystemDrive
ExpectedFullyQualifiedErrorId = "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand"
FromSession = $true
}
@{
Path = ''
Destination = $env:SystemDrive
ExpectedFullyQualifiedErrorId = "ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand"
FromSession = $true
}
@{
Path = "$env:SystemDrive\nonexistdir\*"
Destination = "$env:SystemDrive\psTest"
ExpectedFullyQualifiedErrorId = "RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand"
FromSession = $true
}
)
foreach ($testCase in $invalidSourcePathtestCases) {
Test-CopyItemError @testCase
}
$invalidDestinationPathtestCases = @(
@{
Path = $testFilePath
Destination = ".\Source"
ExpectedFullyQualifiedErrorId = "RemotePathIsNotAbsolute,Microsoft.PowerShell.Commands.CopyItemCommand"
}
@{
Path = $testFilePath
Destination = $env:SystemDrive + "\X\A\B\C"
ExpectedFullyQualifiedErrorId = "RemotePathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand"
}
@{
Path = $testFilePath
Destination = $null
ExpectedFullyQualifiedErrorId = "CopyItemRemoteDestinationIsNullOrEmpty,Microsoft.PowerShell.Commands.CopyItemCommand"
}
@{
Path = $testFilePath
Destination = ""
ExpectedFullyQualifiedErrorId = "CopyItemRemoteDestinationIsNullOrEmpty,Microsoft.PowerShell.Commands.CopyItemCommand"
}
@{
Path = "$env:SystemDrive\nonexistdir\*"
Destination = "$env:SystemDrive\psTest"
ExpectedFullyQualifiedErrorId = "PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand"
}
)
foreach ($testCase in $invalidDestinationPathtestCases) {
Test-CopyItemError @testCase
}
}
}
Describe "Validate Copy-Item error for target sessions not in FullLanguageMode." -Tags "Feature" {
BeforeAll {
$testDirectory = "TestDrive:\"
# Create the test file and directories.
$source = "$testDirectory\Source"
$destination = "$testDirectory\Destination"
New-Item $source -ItemType Directory -Force | Out-Null
New-Item $destination -ItemType Directory -Force | Out-Null
$testFilePath = Join-Path $source "testfile.txt"
"File test content" | Out-File $testFilePath -Force
# Keep track of the sessions.
$testSessions = @{}
# Keep track of the session names to be unregistered.
$sessionToUnregister = @()
$languageModes = @("ConstrainedLanguage", "NoLanguage", "RestrictedLanguage")
$id = (Get-Random).ToString()
foreach ($languageMode in $languageModes)
{
$sessionName = $languageMode + "_" + $id
$sessionToUnregister += $sessionName
$configFilePath = Join-Path $testDirectory "test.pssc"
# Create the session.
Write-Host "Creating pssession with '$languageMode' ..."
New-PSSessionConfigurationFile -Path $configFilePath -SessionType Default -LanguageMode $languageMode
Register-PSSessionConfiguration -Name $sessionName -Path $configFilePath -Force | Out-Null
$testSession = New-PSSession -ConfigurationName $sessionName
# Validate that the session is opened.
$testSession.State | Should -Be "Opened"
# Add the new session to the list.
$testSessions[$languageMode] = $testSession
# Remove the pssc file.
Remove-Item $configFilePath -Force -ErrorAction SilentlyContinue
}
}
AfterAll {
$testSessions.Values | Remove-PSSession -ErrorAction SilentlyContinue
$sessionToUnregister | ForEach-Object {
Unregister-PSSessionConfiguration -Name $_ -Force -ErrorAction SilentlyContinue
}
}
foreach ($languageMode in $testSessions.Keys)
{
$session = $testSessions[$languageMode]
It "Copy-Item throws 'SessionIsNotInFullLanguageMode' error for a session in '$languageMode'" {
# FromSession
{ Copy-Item -Path $testFilePath -FromSession $session -Destination $destination -Force -Verbose -ErrorAction Stop } |
Should -Throw -ErrorId "SessionIsNotInFullLanguageMode,Microsoft.PowerShell.Commands.CopyItemCommand"
# ToSession
{ Copy-Item -Path $testFilePath -ToSession $session -Destination $destination -Force -Verbose -ErrorAction Stop } |
Should -Throw -ErrorId "SessionIsNotInFullLanguageMode,Microsoft.PowerShell.Commands.CopyItemCommand"
}
}
}
Describe "Copy-Item can use Recurse and Exclude together" -Tags "Feature" {
Context "Local and Remote Tests" {
BeforeAll {
$s = New-PSSession -ComputerName . -ErrorAction SilentlyContinue
if (-not $s)
{
throw "Failed to create PSSession for remote copy operations."
}
$null = New-Item -ItemType Directory -Path "TestDrive:\Parent\Sub"
$null = New-Item -Path "TestDrive:\Parent\p1.txt" -Value "test"
$null = New-Item -Path "TestDrive:\Parent\p2.txt" -Value "test"
$null = New-Item -Path "TestDrive:\Parent\s4.txt" -Value "test"
$null = New-Item -Path "TestDrive:\Parent\Sub\s1.txt" -Value "test"
$null = New-Item -Path "TestDrive:\Parent\Sub\s2.txt" -Value "test"
$null = New-Item -Path "TestDrive:\Parent\Sub\s3.txt" -Value "test"
$null = New-Item -Path "TestDrive:\Parent\Sub\p3.txt" -Value "testcl"
}
It "can exclude files at sub directory" {
Copy-Item -Path TestDrive:\Parent\* -Recurse -Exclude s*.txt -Destination TestDrive:\Temp -Force
$copiedFiles = Get-ChildItem -Recurse -Path TestDrive:\Temp
$copiedFiles.Count | Should -Be 3
}
It "can exclude files at sub directory to a session" {
Copy-Item -Path TestDrive:\Parent\* -Recurse -Exclude s*.txt -Destination $TestDrive\Temp2 -Force -ToSession $s
$copiedFiles = Get-ChildItem -Recurse -Path TestDrive:\Temp
$copiedFiles.Count | Should -Be 3
}
It "can exclude files at sub directory from a session" {
Copy-Item -Path $TestDrive\Parent\* -Recurse -Exclude s*.txt -Destination TestDrive:\Temp3 -FromSession $s
$copiedFiles = Get-ChildItem -Recurse -Path TestDrive:\Temp2
$copiedFiles.Count | Should -Be 3
}
AfterAll {
Remove-PSSession -Session $s -ErrorAction SilentlyContinue
}
}
}
Describe "Copy-Item remotely bug fixes" -Tags "Feature" {
BeforeAll {
$s = New-PSSession -ComputerName . -ErrorAction SilentlyContinue
if (-not $s)
{
throw "Failed to create PSSession for remote copy operations."
}
$originalContent = "test file 1 - Source"
$newContent = "This is some new content"
$null = New-Item -ItemType Directory -Path "TestDrive:\Source"
$null = New-Item -ItemType Directory -Path "TestDrive:\Destination"
}
AfterAll {
Remove-PSSession -Session $s -ErrorAction SilentlyContinue
}
BeforeEach {
# Create the same file in the source and destination
Set-Content -Path "TestDrive:\Source\testFile1.txt" -Value $originalContent -Force
Set-Content -Path "TestDrive:\Destination\testFile1.txt" -Value $originalContent -Force
}
Context "Copy-Item remotely overwrites a destination file if it exists." {
BeforeEach {
# Overwrite the source file
Set-Content -Path "TestDrive:\Source\testFile1.txt" -Value $newContent
}
It "Copy item -tosession overwrites the content of an existing file." {
# Copy file to session
Copy-Item -Path "TestDrive:\Source\testFile1.txt" -Destination "$TestDrive\Destination\testFile1.txt" -ToSession $s
# Validate the the file was overwritten
$fileContent = Get-Content "TestDrive:\Destination\testFile1.txt" -ErrorAction SilentlyContinue -Raw
$fileContent | Should -Match $newContent
}
It "Copy item -fromsession overwrites the content of an existing file." {
# Copy file to session
Copy-Item -Path "$TestDrive\Source\testFile1.txt" -Destination "TestDrive:\Destination\testFile1.txt" -FromSession $s
# Validate the the file was overwritten
$fileContent = Get-Content "TestDrive:\Destination\testFile1.txt" -ErrorAction SilentlyContinue -Raw
$fileContent | Should -Match $newContent
}
}
Context "Copy-Item remotely creates a destination file if it does not exist." {
BeforeEach {
if (Test-Path "TestDrive:\AnotherDestination")
{
Remove-Item "TestDrive:\AnotherDestination" -Force -Recurse -ErrorAction SilentlyContinue
}
$null = New-Item -ItemType Directory -Path "TestDrive:\AnotherDestination"
# Ensure the file does not exist
"TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" | Should -Not -Exist
}
It "Copy-Item -tosession creates the file if it does not exist on the remote destination." {
# Copy file to session
Copy-Item -Path "TestDrive:\Source\testFile1.txt" -Destination "$TestDrive\AnotherDestination\FileThatDoesNotExist.txt" -ToSession $s
# Verify that the file was created
"TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" | Should -Exist
}
It "Copy-Item -fromsession creates the file if it does not exist on the local machine." {
# Copy file from session
Copy-Item -Path "$TestDrive\Source\testFile1.txt" -Destination "TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" -FromSession $s
# Verify that the file was created
"TestDrive:\AnotherDestination\FileThatDoesNotExist.txt" | Should -Exist
}
}
}