PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Ответить
 • Просмотры: 1
Аватара пользователя
epoddubniy

PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение epoddubniy »

Здравствуйте.

Помогите пожалуйста доработать скрипт (или создать новый)





Код:

Код: Выделить всё

# переменные
$Data=Get-Date -Format "dd.MM.yyyy"
$CurrentDay=get-date -format "%d"
$newfoldername = [string]$Data +"_"+ "User"
$Source="\\USER-PC\c$\users\User\Desktop"
$Dest="H:\USERPROFILE-BACKUP\Increment\$newfoldername"
$MakeDir=New-Item -Path $Dest -ItemType Directory -force
$getFiles=Get-ChildItem $Source -Recurse | where-object {$_.lastwritetime -lt (get-date).date.adddays(1) -and $_.lastwritetime -ge (get-date).date.adddays(-1)}
#непосредственно скрипт
# копирование с сохранением структуры
$MakeDir
$getFiles | ForEach-Object -Process {Copy-Item -Path $_.FullName -Destination $Dest}

Получилось, чтобы powershell рекурсивно отобрал файлы и скопировал в каталог назначения, а как сделать, чтобы "в соответствующий каталог" копировал - не смог придумать
Аватара пользователя
Sham

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение Sham »

Copy-Item сам по себе рекурсивно копирует с учётом -exclude или -include.

Код:

Код: Выделить всё

Copy-Item -Path $Source\* -Destination $Dest -Recurse -Include $getFiles
Аватара пользователя
Sham

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение Sham »

Цитата Sham:



Copy-Item сам по себе рекурсивно копирует с учётом -exclude или -include.
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




Это Вы погорячились, понадеявшись на разработчиков из микрософт... увы не всё так радужно, как кажется...

В случае копирования каталога целиком, это работает, а вот в случае выборочного копирования, увы и ах, сохранения структуры не получится...




Цитата epoddubniy:



чтобы powershell рекурсивно отобрал файлы и скопировал в каталог назначения
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




Когда-то что-то подобное делал:

Код: Выделить всё

<#
	.SYNOPSIS 
		Копирование или псевдоперемещение файлов и каталогов с сохранением структуры
	.Description
		Скрипт предназначен для копирования или перемещения файлов из одного каталога
		в другой, при этом сохраняется вложенная структура каталогов. Фактически, 
		перемещение не выполняется, вместо него работает копирование с последующим 
		удалением скопированнных итемов.
	.Parameter Source
		Необязательный: Исходный каталог для выборки элементов. Указывается либо 
		относительный, либо абсолютный путь.
	.Parameter Destination
		Необязательный: Целевой каталог. Указывается либо относительный, либо 
		абсолютный путь.
	.Parameter Include
		Необязательный: маска(и) для включения файлов в выборку
	.Parameter Exclude
		Необязательный: маска(и) для исключения файлов из выборки
	.Parameter Delete
		Переключатель: Если указан, то будут удалены исходные файлы, включенные в выборку,
		рекурсивно
	.Parameter Emptydelete
		Переключатель: Если указан, то будут удалены пустые подкаталоги в исходном каталоге,
		рекурсивно
	.Example
		.\script.ps1 -sourc "D:\FOLDER1" -dest "d:\Folder2" -incl '*.pdf','*.txt' -excl '*_out.*' -del
		Это пример перемещения файлов по маскам  '*.pdf','*.txt' с исключением из выборки по маске
		'*_out.*', с последующим удалением исходных элементов. Пустые каталоги не удаляются.
	.Example
		.\script.ps1
		Это пример копирования/перемещения файлов/каталогов, с сохранением структуры, но
		по указанным в самом скрипте параметрам...
	.Link
		[удалено во избежание нарушения]
	.Notes
		Created By YuS
		Version: 1.00
		Date: 20.01.2021
		Purpose/Change:	Первая версия
#>
# requires v 3.0
param (
	[string]
	$source = ".\Folder1",
	[string]
	$destination = ".\Folder2",
	[string[]]
	$include = '*.*',
	[string[]]
	$exclude = '',
	[switch]
	$delete,
	[switch]
	$emptydelete
)
$src = gi -lit $source -force
# копирование файлов с сохранением структуры
dir -lit $src.fullname -inc $include -exc $exclude -rec -force|copy -d {
	$d = split-path $_.fullname.replace("$($src.fullname)",$destination)
	if (!(test-path -lit $d)){md $d -force} else {$d}
} -force #-whatif
if ($delete) {
	# удаляем все скопированные файлы
	dir -lit $src.fullname  -inc $include -exc $exclude  -rec -force -file|
	del -force -rec
}
if ($emptydelete) {
	# удаляем пустые каталоги
	dir -lit $src.fullname -rec -dir -force|sort{$_.fullname.length} -des|%{
		if((dir -lit $_.fullname -rec -force) -eq $null){
			del -lit $_.fullname -force
		}
	}
}
Аватара пользователя
YuS_2

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение YuS_2 »

Sham, не получилось. Запустил скрипт. Powershell никакой ошибки не выдал, но ничего и не скопировал, хотя измененные файлы со вчерашнего дня были.



YuS_2, может быть не совсем корректно изложил цель задачи... Попробую подробно, пошагово описать, то чего я хотел добиться и что получилось



У меня есть каталог



Код:

Код: Выделить всё

\\USER-PC\c$\users\User\Desktop

, в этом каталоге много папок и подпапок и каждый день в этих подпапках изменяются файлы

Вот пример подкаталогов



Код:

Код: Выделить всё

\\USER-PC\c$\users\User\Desktop\Word
\\USER-PC\c$\users\User\Desktop\Сканы
\\USER-PC\c$\users\User\Desktop\Документы

Из этих папок я хочу скопировать только те файлы, которые были изменены вчера, но таким образом, чтобы в каталоге назначения они располагались в тех же папках и подпапках, откуда были скопированы.



Получить список файлов, измененных вчера, и скопировать их в одну кучу в каталог назначения у меня получилось, то есть в корень этого каталога



Код:

Код: Выделить всё

H:\USERPROFILE-BACKUP\Increment\$newfoldername

скопировались все файлы из папок и подпапок удовлетворяющие условию, но как сделать, чтобы например



Код:

Код: Выделить всё

\\USER-PC\c$\users\User\Desktop\Word\Реестр1.rtf

скопировался в

Код:

Код: Выделить всё

 H:\USERPROFILE-BACKUP\Increment\$newfoldername\Desktop\Word\Реестр1.rtf

Ну и все остальные файлы - по аналогии...




Цитата YuS_2:



- линк на ресурс, где был опубликован скрипт, удален... если что-то непонятно, спрашивайте.

Конкретно для Вашего случая (скрипта), строка запуска будет такой:
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




Да, я встречал Ваш скрипт, но не смог его адаптировать под свою задачу


Цитата YuS_2:



.\script.ps1
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




вот эта строка оказалась непонятной, непонятной ее значение, то есть, что мне нужно заменить в своем скрипте этим значением


Аватара пользователя
epoddubniy

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение epoddubniy »

$Data=Get-Date -Format "dd.MM.yyyy"

$CurrentDay=get-date -format "%d"



$Source=""

$Dest=""







YuS_2, попробовал понять и отредактировать Ваш скрипт, но у меня не получилось. Запускать планирую через планировщик. Помогите с написанием строки запуска и поправкой в самом скрипте





Код:

Код: Выделить всё

param (
    $Data = Get-Date -Format "dd.MM.yyyy"
    $CurrentDay = get-date -format "%d"
    $CurrentDayDD = get-date -format "dd"
    $newfoldername = [string]$Data +"_"+ "User"
    $MakeDir = New-Item -Path $Dest -ItemType Directory -force
    $getFiles = Get-ChildItem $Source -Recurse | where-object {$_.lastwritetime -lt (get-date).date.adddays(1) -and $_.lastwritetime -ge (get-date).date.adddays(-1)
    [string]
	$Source = "\\USER-PC\c$\users\User\Desktop"
	[string]
	$destination = "H:\USERPROFILE-BACKUP\Increment\$newfoldername"
	[string[]]
	$include = $getFiles
)
$src = gi -lit $source -force
# копирование файлов с сохранением структуры
dir -lit $src.fullname -inc $include -rec -force|copy -d {
	$d = split-path $_.fullname.replace("$($src.fullname)",$destination)
	if (!(test-path -lit $d)){md $d -force} else {$d}
} -force #-whatif
Аватара пользователя
epoddubniy

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение epoddubniy »

Цитата epoddubniy:



вот эта строка оказалась непонятной, непонятной ее значение, то есть, что мне нужно заменить в своем скрипте этим значением
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




это строка запуска скрипта, то бишь всё, что в коде, надо записать в файл script.ps1 и запускать уже из Вашего скрипта, предварительно поместив файл рядом с вашим файлом скрипта...

Ну или оформить всё в функцию и вызывать её прямо в Вашем же скрипте...



Код:

Код: Выделить всё

function copy-str {
	param (
		[string]
		$source = ".\Folder1",
		[string]
		$destination = ".\Folder2",
		[string[]]
		$include = '*.*',
		[string[]]
		$exclude = '',
		[switch]
		$delete,
		[switch]
		$emptydelete
	)
	$src = gi -lit $source -force
	# копирование файлов с сохранением структуры
	dir -lit $src.fullname -inc $include -exc $exclude -rec -force|copy -d {
		$d = split-path $_.fullname.replace("$($src.fullname)",$destination)
		if (!(test-path -lit $d)){md $d -force} else {$d}
	} -force #-whatif
	if ($delete) {
		# удаляем все скопированные файлы
		dir -lit $src.fullname  -inc $include -exc $exclude  -rec -force -file|
		del -force -rec
	}
	if ($emptydelete) {
		# удаляем пустые каталоги
		dir -lit $src.fullname -rec -dir -force|sort{$_.fullname.length} -des|%{
			if((dir -lit $_.fullname -rec -force) -eq $null){
				del -lit $_.fullname -force
			}
		}
	}
}
#...  здесь текст основного скрипта
# а здесь вызов функции:
copy-str -sourc $Source -dest $Dest -incl $getFiles.name

Не знаю как это будет работать с сетевыми путями, мне проверить не на чем...
Аватара пользователя
YuS_2

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение YuS_2 »

Можно подменой папки в пути источника на папку назначения и созданием несуществующих папок через new-item. Не идеально, но рекурсивные папки создаёт и копирует.



Код:

Код: Выделить всё

$getFiles | foreach {
	$new_path = $Dest + $_.FullName.Remove(0, $Source.TrimEnd('\').Length)
	$dir_name = $new_path.Remove($new_path.LastIndexOf('\'))
	if (-not (Test-Path $dir_name -PathType 'Container')) {
		New-Item -Path $dir_name -ItemType 'Directory' -Force -Verbose
	}
	Copy-Item $_.FullName $new_path -Force -Verbose
}
Аватара пользователя
Sham

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение Sham »

Можно подменой папки в пути источника на папку назначения и созданием несуществующих папок через new-item. Не идеально, но рекурсивные папки создаёт и копирует.



Код:

Код: Выделить всё

$getFiles | foreach {
	$new_path = $Dest + $_.FullName.Remove(0, $Source.TrimEnd('\').Length)
	$dir_name = $new_path.Remove($new_path.LastIndexOf('\'))
	if (-not (Test-Path $dir_name -PathType 'Container')) {
		New-Item -Path $dir_name -ItemType 'Directory' -Force -Verbose
	}
	Copy-Item $_.FullName $new_path -Force -Verbose
}
Аватара пользователя
DJ Mogarych

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение DJ Mogarych »

Цитата DJ Mogarych:



Почитайте про robocopy, очень полезная вещь.
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




да, читал, пробовал пользовать - не поладил я с ней. Не получилось у меня в этой утилите с рекурсивным отбором файлов по условию.



Sham, Спасибо.


Цитата Sham:



$getFiles | foreach {

$new_path = $Dest + $_.FullName.Remove(0, $Source.TrimEnd('\').Length)

$dir_name = $new_path.Remove($new_path.LastIndexOf('\'))

if (-not (Test-Path $dir_name -PathType 'Container')) {

New-Item -Path $dir_name -ItemType 'Directory' -Force -Verbose

}

Copy-Item $_.FullName $new_path -Force -Verbose

}
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




То что нужно, то, что хотел но не знал как сделать.



Sham, позвольте пожалуйста Вас немного помучить.

Sham, объясните пожалуйста
Цитата Sham:



$_.FullName.Remove(0, $Source.TrimEnd('\').Length)
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




что делает вот эта команда? Как можно догадаться, что после $_.FullName можно поставить точку и еще потом использовать Remove с какими-то параметрами.


Цитата Sham:



$new_path.Remove($new_path.LastIndexOf('\'))
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




Remove - это какой-то модуль для работы со строками? А LastIndexOf - это тоже какая-то команда? А ее только со строками можно использовать и через "точку"?
Аватара пользователя
epoddubniy

Re: PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Сообщение epoddubniy »

Цитата epoddubniy:



Как можно догадаться, что после $_.FullName можно поставить точку и еще потом использовать Remove с какими-то параметрами.
PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов




есть офигенская команда get-member, по пайпу она принимает то что вываливается из предыдущей команды и говорит почти понятным языком, что с этим можно сделать.

например вот так:



Код:

Код: Выделить всё

Get-Item ./ | Get-Member

или из переменной



Код:

Код: Выделить всё

$new_variable | Get-Member
Ответить

Вернуться в «Скриптовые языки администрирования Windows»