ffd39b2853
- Fix PSScriptAnalyzer warnings of type PSAvoidUsingCmdletAliases for 'ForEach-Object' (alias is '%' or 'foreach') - Fix PSScriptAnalyzer warnings of type PSAvoidUsingCmdletAliases for 'Where-Object' (alias is '?' or 'where') - Fix PSScriptAnalyzer warnings of type PSAvoidUsingCmdletAliases for 'Select-Object' (alias is 'select') - Fix PSScriptAnalyzer warnings of type PSPossibleIncorrectComparisonWithNull. Essentially, $null has to be on the left-hand side when using it for comparison. - A Test in ParameterBinding.Tests.ps1 needed adapting as this test used to rely on the wrong null comparison - Replace a subset of tests of kind '($object -eq $null) | Should Be $true' with '$object | Should Be $null'
868 lines
33 KiB
PowerShell
868 lines
33 KiB
PowerShell
# This is a Pester test suite to validate Copy-Item remotely using a remote session.
|
|
#
|
|
# Copyright (c) Microsoft Corporation, 2015
|
|
#
|
|
#
|
|
|
|
# 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 -ea SilentlyContinue
|
|
$actualStreamContent | Should Match $expectedStreamContent
|
|
}
|
|
|
|
BeforeAll {
|
|
$s = New-PSSession -ComputerName . -ea SilentlyContinue
|
|
if (-not $s)
|
|
{
|
|
throw "Failed to create PSSession for remote copy operations."
|
|
}
|
|
|
|
$destinationFolderName = "DestinationDirectory"
|
|
$sourceFolderName = "SourceDirectory"
|
|
$testDirectory = Join-Path "TestDrive:" "copyItemRemotely"
|
|
$destinationDirectory = Join-Path $testDirectory $destinationFolderName
|
|
$sourceDirectory = Join-Path $testDirectory $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 $sourceDirectory "testfileone.txt"
|
|
if (-not $emptyFile)
|
|
{
|
|
"File test content" | Out-File $filePath -Force
|
|
}
|
|
else
|
|
{
|
|
"" | Out-File $filePath -Force
|
|
}
|
|
|
|
if (-not (Test-Path $filePath))
|
|
{
|
|
throw "Failed to create test file $filePath."
|
|
}
|
|
|
|
if ($setReadOnlyAttribute)
|
|
{
|
|
Set-ItemProperty $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 $sourceDirectory $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 $sourceDirectory $file
|
|
$file + "`r`n File test content" | Out-File $filePath -Force
|
|
|
|
if (-not (Test-Path $filePath))
|
|
{
|
|
throw "Failed to create test file $filePath."
|
|
}
|
|
|
|
if ($setReadOnlyAttribute)
|
|
{
|
|
Set-ItemProperty $filePath -Name IsReadOnly -value $true -Force
|
|
}
|
|
|
|
$result.Files += (Get-Item $filePath).FullName
|
|
}
|
|
|
|
return $result
|
|
}
|
|
|
|
function GenerateTestAssembly
|
|
{
|
|
$assemblyPath = Join-Path $env:TEMP TestModule
|
|
$outputPath = Join-Path $assemblyPath TestModule.dll
|
|
|
|
if (-not (Test-Path $assemblyPath))
|
|
{
|
|
New-Item $assemblyPath -Force -ItemType Directory | Out-Null
|
|
}
|
|
|
|
if (-not (Test-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 $destinationDirectory).FullName
|
|
}
|
|
}
|
|
|
|
AfterAll {
|
|
Remove-PSSession -Name $s.Name -ea 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 $testDirectory)
|
|
{
|
|
Remove-Item $testDirectory -Force -ea SilentlyContinue -Recurse
|
|
}
|
|
|
|
# Create testDirectory, and destinationDirectory
|
|
New-Item $testDirectory -ItemType Directory -Force | Out-Null
|
|
New-Item $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'
|
|
|
|
try
|
|
{
|
|
Copy-Item -Path $filePath -ToSession $s -Destination $destinationFolderPath -ErrorAction Stop
|
|
throw "CodeExecuted"
|
|
}
|
|
catch
|
|
{
|
|
$_.FullyQualifiedErrorId | should be $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'
|
|
try
|
|
{
|
|
Copy-Item -Path $filePath -FromSession $s -Destination $destinationFolderPath -ErrorAction Stop
|
|
throw "CodeExecuted"
|
|
}
|
|
catch
|
|
{
|
|
$_.FullyQualifiedErrorId | should be $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 -ea 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
|
|
}
|
|
}
|
|
|
|
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 -ea 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" {
|
|
try
|
|
{
|
|
Copy-Item -Path $path -FromSession $s -Destination $destination -ErrorAction Stop
|
|
throw "CodeExecuted"
|
|
}
|
|
catch
|
|
{
|
|
$_.FullyQualifiedErrorId | should be $expectedFullyQualifiedErrorId
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
It "Copy-Item ToSession -Destination '$path' throws $expectedFullyQualifiedErrorId" {
|
|
try
|
|
{
|
|
Copy-Item -Path $path -ToSession $s -Destination $destination -ErrorAction Stop
|
|
throw "CodeExecuted"
|
|
}
|
|
catch
|
|
{
|
|
$_.FullyQualifiedErrorId | should be $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 -ea SilentlyContinue
|
|
}
|
|
}
|
|
|
|
AfterAll {
|
|
|
|
$testSessions.Values | Remove-PSSession -ea SilentlyContinue
|
|
|
|
$sessionToUnregister | ForEach-Object {
|
|
Unregister-PSSessionConfiguration -Name $_ -Force -ea SilentlyContinue
|
|
}
|
|
}
|
|
|
|
foreach ($languageMode in $testSessions.Keys)
|
|
{
|
|
$session = $testSessions[$languageMode]
|
|
|
|
It "Copy-Item throws 'SessionIsNotInFullLanguageMode' error for a session in '$languageMode'" {
|
|
|
|
# FromSession
|
|
try
|
|
{
|
|
Copy-Item -Path $testFilePath -FromSession $session -Destination $destination -Force -Verbose -ea Stop
|
|
throw "CodeExecuted"
|
|
}
|
|
catch
|
|
{
|
|
$_.FullyQualifiedErrorId | should be "SessionIsNotInFullLanguageMode,Microsoft.PowerShell.Commands.CopyItemCommand"
|
|
}
|
|
|
|
# ToSession
|
|
try
|
|
{
|
|
Copy-Item -Path $testFilePath -ToSession $session -Destination $destination -Force -Verbose -ea Stop
|
|
throw "CodeExecuted"
|
|
}
|
|
catch
|
|
{
|
|
$_.FullyQualifiedErrorId | should be "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 . -ea 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" -ea 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" -ea 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 -ea 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
|
|
}
|
|
}
|
|
}
|