Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

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

Пользователь


Сообщения: 105
Благодарности: 1

Профиль | Отправить PM | Цитировать


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

Код: Выделить весь код
# переменные
$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 рекурсивно отобрал файлы и скопировал в каталог назначения, а как сделать, чтобы "в соответствующий каталог" копировал - не смог придумать

Отправлено: 16:51, 08-02-2022

 

Deadooshka


Сообщения: 2558
Благодарности: 697

Профиль | Отправить PM | Цитировать


Copy-Item сам по себе рекурсивно копирует с учётом -exclude или -include.
Код: Выделить весь код
Copy-Item -Path $Source\* -Destination $Dest -Recurse -Include $getFiles
Это сообщение посчитали полезным следующие участники:

Отправлено: 01:15, 09-02-2022 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1231
Благодарности: 515

Профиль | Отправить PM | Цитировать


Цитата Sham:
Copy-Item сам по себе рекурсивно копирует с учётом -exclude или -include. »
Это Вы погорячились, понадеявшись на разработчиков из микрософт... увы не всё так радужно, как кажется...
В случае копирования каталога целиком, это работает, а вот в случае выборочного копирования, увы и ах, сохранения структуры не получится...

Цитата epoddubniy:
чтобы 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
		}
	}
}
- линк на ресурс, где был опубликован скрипт, удален... если что-то непонятно, спрашивайте.
Конкретно для Вашего случая (скрипта), строка запуска будет такой:
Код: Выделить весь код
.\script.ps1 -sourc $Source -dest $Dest -incl $getFiles.name

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 05:57, 09-02-2022 | #3


Пользователь


Сообщения: 105
Благодарности: 1

Профиль | Отправить PM | Цитировать


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:
- линк на ресурс, где был опубликован скрипт, удален... если что-то непонятно, спрашивайте.
Конкретно для Вашего случая (скрипта), строка запуска будет такой: »
Да, я встречал Ваш скрипт, но не смог его адаптировать под свою задачу
Цитата YuS_2:
.\script.ps1 »
вот эта строка оказалась непонятной, непонятной ее значение, то есть, что мне нужно заменить в своем скрипте этим значением

[code]

Отправлено: 12:17, 09-02-2022 | #4


Пользователь


Сообщения: 105
Благодарности: 1

Профиль | Отправить PM | Цитировать


$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

Отправлено: 12:43, 09-02-2022 | #5


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1231
Благодарности: 515

Профиль | Отправить PM | Цитировать


Цитата epoddubniy:
вот эта строка оказалась непонятной, непонятной ее значение, то есть, что мне нужно заменить в своем скрипте этим значением »
это строка запуска скрипта, то бишь всё, что в коде, надо записать в файл 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
Не знаю как это будет работать с сетевыми путями, мне проверить не на чем...

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 13:44, 09-02-2022 | #6


Deadooshka


Сообщения: 2558
Благодарности: 697

Профиль | Отправить PM | Цитировать


Можно подменой папки в пути источника на папку назначения и созданием несуществующих папок через 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
}
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:34, 09-02-2022 | #7


Аватара для DJ Mogarych

fascinating rhythm


Moderator


Сообщения: 6666
Благодарности: 1553

Профиль | Отправить PM | Цитировать


Почитайте про robocopy, очень полезная вещь.

-------
Powershell 7.x | Powershell 5.1 | ffmpeg (docs)

Это сообщение посчитали полезным следующие участники:

Отправлено: 19:57, 09-02-2022 | #8


Пользователь


Сообщения: 105
Благодарности: 1

Профиль | Отправить PM | Цитировать


Цитата DJ Mogarych:
Почитайте про robocopy, очень полезная вещь. »
да, читал, пробовал пользовать - не поладил я с ней. Не получилось у меня в этой утилите с рекурсивным отбором файлов по условию.

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
} »
То что нужно, то, что хотел но не знал как сделать.

Sham, позвольте пожалуйста Вас немного помучить.
Sham, объясните пожалуйста
Цитата Sham:
$_.FullName.Remove(0, $Source.TrimEnd('\').Length) »
что делает вот эта команда? Как можно догадаться, что после $_.FullName можно поставить точку и еще потом использовать Remove с какими-то параметрами.
Цитата Sham:
$new_path.Remove($new_path.LastIndexOf('\')) »
Remove - это какой-то модуль для работы со строками? А LastIndexOf - это тоже какая-то команда? А ее только со строками можно использовать и через "точку"?

Отправлено: 12:39, 16-02-2022 | #9


Аватара для Elven

Ветеран


Сообщения: 992
Благодарности: 268

Профиль | Сайт | Отправить PM | Цитировать


Цитата epoddubniy:
Как можно догадаться, что после $_.FullName можно поставить точку и еще потом использовать Remove с какими-то параметрами. »
есть офигенская команда get-member, по пайпу она принимает то что вываливается из предыдущей команды и говорит почти понятным языком, что с этим можно сделать.
например вот так:
Код: Выделить весь код
Get-Item ./ | Get-Member
или из переменной
Код: Выделить весь код
$new_variable | Get-Member
Это сообщение посчитали полезным следующие участники:

Отправлено: 15:59, 16-02-2022 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - [решено] Копирование из сети в локальную папку с сохранением структуры каталогов

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Любой язык - [решено] Копирование\перемещение с сохранением структуры папок xan08 Скриптовые языки администрирования Windows 6 19-12-2018 18:52
PowerShell - Построчное копирование папок, с сохранением структуры или копирования из файла - Powe morgan-12l1 Скриптовые языки администрирования Windows 2 17-07-2018 18:53
VBS/WSH/JS - Копирование файлов из каталогов и подкаталогов с сохранением структуры подкаталогов spke Скриптовые языки администрирования Windows 0 10-04-2013 23:58
CMD/BAT - [решено] Копирование отдной структуры каталогов в другую siff009 Скриптовые языки администрирования Windows 6 01-06-2012 13:23
CMD/BAT - [решено] Конвертирование файлов с сохранением структуры каталогов Sarge81 Скриптовые языки администрирования Windows 3 17-09-2010 07:12




 
Переход