Powershell копирование файлов по дате
Просмотр содержимого дисков Windows PowerShell и управление хранящимися на них элементами аналогично управлению файлами и папками на физических дисках Windows. В этой статье описывается выполнение конкретных задач по управлению файлами и папками с помощью PowerShell.
Получение списка файлов и папок, содержащихся в папке
Извлечь все элементы непосредственно из папки можно с помощью командлета Get-ChildItem . Для отображения скрытых и системных элементов добавьте необязательный параметр Force. Например, эта команда отображает непосредственное содержимое диска C Windows PowerShell (которое совпадает с содержимым физического диска C Windows):
Эта команда выводит только элементы, содержащиеся на диске непосредственно, так же как и команда DIR оболочки Cmd.exe или команда ls оболочки UNIX. Для показа вложенных элементов необходимо также указать параметр -Recurse . (Время выполнения этой операции будет очень велико.) Для вывода всего содержимого диска C введите:
Командлет Get-ChildItem позволяет отфильтровать элементы с помощью параметров Path, Filter, Include и Exclude, но обычно осуществляется лишь фильтрация по имени. Сложную фильтрацию на основе других свойств элементов можно выполнить с помощью Where-Object .
Следующая команда находит все исполняемые файлы в папке Program Files, которые были в последний раз изменены после 1 октября 2005 г. и размер которых не менее одного мегабайта и не более десяти мегабайт:
Копирование файлов и папок
Копирование выполняется с помощью командлета Copy-Item . Следующая команда создает резервную копию C:\boot.ini в C:\boot.bak:
Если целевой файл уже существует, то попытка копирования завершается неудачей. Чтобы перезаписать имеющийся целевой файл, используйте параметр Force.
Эта команда работает, даже если целевой объект доступен только для чтения.
Так же выполняется и копирование папок. Эта команда копирует папку C:\temp\test1 в новую папку C:\temp\DeleteMe рекурсивно.
Можно также скопировать избранные элементы. Следующая команда копирует все файлы TXT, содержащиеся в папке C:\data , в папку C:\temp\text :
Для копирования элементов файловой системы можно использовать и другие средства. В Windows PowerShell по-прежнему работают команды XCOPY, ROBOCOPY и такие COM-объекты, как Scripting.FileSystemObject. Например, можно воспользоваться COM-классом Scripting.FileSystem сервера сценариев Windows для создания резервной копии файла C:\boot.ini в файле C:\boot.bak :
Создание файлов и папок
Создание новых элементов осуществляется одинаковым образом всеми поставщиками Windows PowerShell. Если поставщик Windows PowerShell поддерживает более одного типа элементов (например, поставщик Windows PowerShell FileSystem различает каталоги и файлы), необходимо указать тип элемента.
Эта команда создает папку C:\temp\New Folder :
Эта команда создает пустой файл C:\temp\New Folder\file.txt .
При использовании параметра Force с командой New-Item для создания папки, которая уже существует, она не перезапишет и не заменит папку. Будет просто возвращен имеющийся объект папки. Однако, если использовать New-Item -Force в уже имеющимся файле, файл будет полностью перезаписан.
Удаление всех файлов и папок, содержащихся в папке
Удалить вложенные элементы можно с помощью командлета Remove-Item , однако он потребует подтверждения удаления, если элемент сам что-нибудь содержит. Например, при попытке удаления папки C:\temp\DeleteMe , которая содержит другие элементы, Windows PowerShell предварительно предложит подтвердить удаление этой папки:
Если подтверждение для каждого вложенного элемента нежелательно, задайте параметр Recurse:
Подключение локальной папки как диска
Отобразить локальную папку можно с помощью команды New-PSDrive . Следующая команда создает локальный диск P: , корневым каталогом которого является локальный каталог Program Files, отображающийся только в сеансе PowerShell:
Как и при использовании сетевых дисков, диски, отображенные в Windows PowerShell, немедленно становятся доступными оболочке Windows PowerShell. Чтобы создать подключенный диск, отображающийся в проводнике, нужен параметр -Persist . Но с этим параметром можно использовать только удаленные пути.
Чтение текстового файла в массив
Одним из наиболее общих форматов хранения текстовых данных является файл, отдельные строки которого рассматриваются как отдельные элементы. Командлет Get-Content используется для чтения всего файла за один шаг, как показано далее:
Командлет Get-Content сразу рассматривает данные, считанные из файла, как массив с одним элементом на строку содержимого файла. Убедиться в этом можно, проверив свойство Length полученного содержимого:
Эта команда наиболее полезна для непосредственного ввода в Windows PowerShell информационных списков. Например, можно хранить в файле C:\temp\domainMembers.txt список имен компьютеров или IP-адресов по одному имени на каждую строку файла. Вы можете использовать командлет Get-Content , чтобы извлечь содержимое файла и поместить его в переменную $Computers :
Теперь переменная $Computers представляет собой массив, содержащий в каждом элементе имя компьютера.
Я пытаюсь скопировать файлы с датой создания, равной заданной дате, но безуспешно переданные аргументы - это текущая дата 2/12/2020 , и сегодня создано несколько файлов, но ничего не копируется что мне не хватает?
КОД
2 ответа
Вам нужно сократить время
При работе с PowerShell следует помнить о двух вещах.
- PowerShell объектно-ориентирован.
- PowerShell использует конвейеры.
Если вы сможете придерживаться этих правил, у вас будет больше возможностей и ваша работа будет проще.
Вы хорошо поработали с конвейером.
Вот несколько инструментов для исследования предметной стороны вещей.
Какие объекты сравниваются?
Здесь я буду использовать формат даты для моей локали. Я вижу, вы используете день-месяц-год.
Вы можете использовать Get -Член для исследования объектов в PowerShell.
Здесь мы видим, что наша строка даты - это System.String .
Я хотел бы знать, что это за тип объекта CreationTime .
Здесь мы видим, что CreationTime - это System.DateTime .
Пусть наши значения будут одного типа.
Если вы хотите провести сравнение строк в стиле оболочки, вас ничто не остановит. Но тогда вам будет не хватать всего богатства объектов PowerShell.
В принципе, мы сравниваем две даты. Итак, давайте преобразуем наш строковый ввод в DateTime объект.
Обратите внимание, что когда мы вводим приведение строки даты, такой как "12/2/2020" к объекту DateTime , время автоматически заполняется для Hour , Minute , и свойства Second . По умолчанию используется полночь.
Решение проблемы со сравнением дат.
Давайте посмотрим на один из объектов DateTime из моего предыдущего запроса.
В моем конкретном случае в моем файле указана дата Saturday, September 26, 2020 10:57:33 AM .
Объекты DateTime всегда включают время. В нашем случае нас не волнует время. Итак, один из способов решения нашей проблемы - установить одинаковое значение временной части наших объектов. Затем, когда мы сравниваем два объекта, только часть даты может повлиять на результат.
Давайте посмотрим на свойства и методы DateTime, чтобы узнать, может ли что-нибудь нам помочь.
Первое свойство в списке - Дата. Кажется, это может быть интересно. Посмотрим на это.
Получает компонент даты этого экземпляра.
Новый объект с той же датой, что и у этого экземпляра, и значением времени, установленным в полночь 12:00:00 (00:00:00).
Похоже, это может быть полезно.
Помните, когда мы вводим приведение нашей строковой даты, мы получали объект DateTime с частью времени, установленным на полночь.
Здесь мы берем дату и возвращаем ту же дату со временем, установленным на полночь.
Теперь у нас есть способ установки времени для ввода строки и создания файла в одно и то же значение. Итак, когда мы сравниваем эти объекты DateTime, мы будем сравнивать только части даты. Это решит нашу проблему.
Продемонстрируем необходимый код.
Окончательный ответ
Здесь я также добавил параметры со значениями по умолчанию. Мы можем вызвать findLogs так же, как и раньше. Но у нас также есть возможность изменить способ работы функции, не переписывая ее.
Я также использовал FullName, чтобы упростить копирование файла.
В моей среде мне удалось скопировать один из моих букмарклетов в резервную папку:
PowerShell командлет Copy-Item используется для копирования файлов между локальными, сетевыми каталогами или между компьютерами по сети через WinRM. Командлет Copy-Item предоставляет большое количество опций, которые можно использовать в разных сценариях копирования файлов и каталогов (по своим возможностям этот командлет почти не уступает утилите robocopy). Например:
- перезапись файлов (override)
- фильтрация по имени/шаблону
- исключение по имени/шаблону
- Verbose режим
- Копирование файлов с/на удаленные компьютеры
Начнем с простых примеров использования Copy-Item и будем переходить к более сложным.
Копирование файлов и каталогов
Чтобы скопировать один файл 1.txt из каталога C:\SourceFolder\ в F:\DestFolder\, выполните:
Copy-Item -Path "C:\SourceFolder\1.txt" -Destination "F:\DestFolder\1.txt"
Можно использовать сокращенный синтаксис командлета, пропустив указание параметров Path и Destination:
cpi "C:\SourceFolder\1.txt" "F:\DestFolder\1.txt"
Теперь скопируем каталог C:\SourceFolder\folder в F:\DestFolder\folder. В папке folder находится файл 1.txt. Обратите внимание что без ключа –Recurse, папка folder копируется без содержимого:
Copy-Item -Path "C:\SourceFolder\folder" -Destination "F:\DestFolder\folder" -Recurse
С помощью Copy-Item также можно просто объединить файлы из несколько директорий в одну (слияние директории), для этого нужно перечислить директории в ключе –Path:
Copy-Item -Path "C:\SourceFolder\*", "C:\SourceFolder2\*", "C:\SourceFolder3\*" -Destination "F:\DestFolder\"
Копирование с заменой и копирование с заменой read-only файлов
Для перезаписи файла с атрибутом read-only, нужно использовать ключ -Force. Если его не использовать, вы получите ошибку “отказано в доступе по пути… CopyFileInfoItemUnauthorizedAccessError”.
Чтобы скопировать файл с перезаписью файла с read-only атрибутом используйте параметр Force.
Copy-Item -Path "C:\SourceFolder\1.txt" -Destination "F:\DestFolder\1.txt" -Force
Совет. Чтобы не путаться, ключ –Force можно рассматривать как ключ для копирования с заменой.Чтобы Copy-Item скопировал файлы из одной папки в другую без замены существующих файлов, можно использовать этот простой скрипт
Copy-Item (Join-Path "C:\SourceFolder\" "*") "F:\DestFolder\" -Exclude (Get-ChildItem "F:\DestFolder\") -Recurse
Этот скрипт скопирует все файлы и папки из C:\SourceFolder в F:\DestFolder без замены файлов уже существующих в F:\DestFolder
Копирование с фильтрацией по шаблону
С помощью Copy-Item можно скопировать файлы/директории выбранные с помощью wildcard символа * или с помощью символа ?. Также поддерживаются некоторые регулярные выражения
Для примера возьмём такую структуру файлов:
Выполним копирование командой:
Copy-Item -Path "C:\SourceFolder\fol*" -Destination "F:\DestFolder\"
Результат в F:\DestFolder\
Теперь чистим папку назначения и выполняем:
Copy-Item -Path "C:\SourceFolder\folder1" -Destination "F:\DestFolder\"
Папка без цифры в окончании не скопировалась, потому что folder1 подразумевает что после folder будет как минимум еще 1 символ между 0 и 3
Исключение файлов при копировании
С помощью ключа –Exclude можно исключить файлы при копировании. Например, следующай команда скопирует все файлы кроме файлов с расширением txt.
Copy-Item -Path "C:\SourceFolder\*" -Destination "F:\DestFolder\" -Recurse -Force -Exclude "*.txt"
Аналогичным же образом можно применить ключ –Include, например
Copy-Item -Path "C:\SourceFolder\*" -Destination "F:\DestFolder\" -Recurse -Force -Include "*.txt"
Скопирует только txt файлы. Хотя для простоты гораздо удобнее использовать при копировании вид -Path "C:\SourceFolder\*.txt" .
Копирование файлов на удаленный компьютер по сети
Copy-File может копировать не только по SMB протоколу, но и через WinRM (WSMan).
Создайте новую сессию с компьютером testnode1 и выполните копирование в её контексте:
$session = New-PSSession -ComputerName testnode1
Copy-Item -Path "C:\SourceFolder\*" -ToSession $session -Destination "C:\SourceFolder\" -Recurse -Force
Эта команда скопирует файлы с локального компьютера из директории C:\SourceFolder на компьютер testnode1 в C:\SourceFolder\.
Примечание. Доступность WSMan на удаленном компьютере можно проверить с помощью командлета Test-WSMan.Test-WSMan -ComputerName testnode1
Если WSMan не настроен, вы можете выполнить его быструю конфигурацию. Для этого откройте командную строку с правами администратора и выполните winrm quickconfig
Также можно копировать и через обычные сетевые SMB шары, для этого просто используйте UNC формат сетевого пути.
Copy-Item -Path "C:\SourceFolder\*" -Destination "\\testnode1\C$\copy_tutorial\"
Можно скопировать файл с удаленного компьютера. Принцип такой же, как и при копировании файлов на удаленный компьютер, за исключением параметра –ToSession, вместо него нужно использовать –FromSession:
$session = New-PSSession -ComputerName testnode1
Copy-Item -FromSession $session -Path "C:\SourceFolder\*" -Destination "F:\DestFolder\" -Recurse -Force
Эта команда скопирует содержимое папки C:\SourceFolder\ с компьютера testnode1 на локальный компьютер в директорию F:\DestFolder
Ключ PassThru
Командлет Copy-Item (как и многие другие командлеты PowerShell) не возвращает результатов в консоль. Параметр PassThru применяется скриптах, или для лог-файлов, когда нужно получить список скопированных файлов и работать с ним дальше. Рассмотрим пример
$items = Copy-Item -Path "C:\SourceFolder\*" –Destination "\\testnode1\C$\copy_tutorial\" -PassThru
Переменная $items будет содержать список скопированных файлов, с которым вы можете работать дальше.Это значит что вы можете напрямую работать с этими файлами. Например выполнив команду Remove-Item $items[0] , вы удалите директорию folder.
Ключ Verbose
При использовании ключа -Verbose вы получите подробный лог операций копирования. Например, вывод команды
Copy-Item -Path "C:\SourceFolder\*.txt" -Destination "F:\DestFolder\" -Recurse -Force -Verbose
Несколько полезных скриптов с Copy-Item
Скопировать только файлы:
Get-ChildItem "C:\SourceFolder" -File -Recurse | Copy-Item -Destination "F:\DestFolder"
Скопировать структуру папок, без файлов:
$path = Get-ChildItem "C:\SourceFolder" -Recurse | ?
$dest = "F:\DestFolder\"
$parent = $path[0].Parent.Name
$path | foreach $_.FullName -match "$parent.+"
New-Item -ItemType directory ($dest + $Matches[0])
>
Copy-Item очень простой и удобный в использовании командлет PowerShell для выполнения операций копирования и перемещения файлов. В сочетании с другими инструментами PowerShell, Copy-Item также является мощным инструментом для написания скриптов.
спасибо за ссылку. но помогите в ней разобратся я начинающий пользователь powershell и хотел бы разобраться в данном примере. можете пояснить на примере реальной папки?
Function Search-OldFiles param ($day,$path,[switch]$search)
Похожий на ваш. я его решил следующим образом:
Вот так проверяем изменилась ли дата последней записи в файл. Посмотрит вот тут , возможно поможет в решении вопроса.
В вашем случае нужно получить рекурсивно все объекты в первой папке, и сверять эти объекты со второй папкой, меняя частично путь (тот, что до корня текущей папки). Если файл отличается, то заливаем новую версию. Если файла не существует, то тоже заливаем новую версию.
Делать было нечего и написал тут скриптик:
Dest1 И Dest2 это корни папок, которые нужно сравнивать. Суть алгоритма. Берется рекурсивно все файлы из Папки1 и смотрится если такой файл в папке2. Если нету, то копируется, если есть, то проверятся есть ли модификации между файлами в Папке1 и папке2.
Второй цикл проверяет папку2. Берет рекурсивно все файлы, потом смотрит, есть ли такой файл в папке1 , если нету, то удаляет из папки2.
ваш пример к сожалению не работает, он проверяет на существование файлов в папке 2 но выводит что они там есть при том, что папка 2 пуста. у меня стоит powershell 1.0 может в этом проблема.
я приведу пример работы части скрипта в чем здесь загвоздка может кто-нибудь поймет:
$dest1= "f:\1"
$dest2= "f:\2"
$files1 = dir -path $dest1 -recurse -include *.*
$files2 = dir -path $dest1 -recurse -include *.*
foreach ($file in $files1) if ((test-path -path dest2) -eq $true) write-host $file.name "существует в папке 2"
>
else >
здесь он выводит что файлы не существуют , даже если они и есть в папке 2, в чем ошибка? как работает test-path?
первое что бросилось в глаза:
if ((test-path -path dest2) -eq $true)
вы проверяете на существование папки, а не файлов в ней. заметьте, что у меня есть строчка
Большое спасибо за скрипт еще раз. у меня правда не работает строка
$Dest1ToDest2= $File.FullName.Replace($Dest1, $Dest2), если вывести write-host $Dest1ToDest2? , то увидим что powershell расматривает объект со старым путем из переменной dest1, но при указании вместо переменных $Dest1 и $dest2 ":/1" и ":/2" начинает работать и при этом путь у объекта изменяется. в чем здесь загвоздка? так не очень удобно получается - нельзя применить в виде параметров скрипта в полной мере. может все дело в powershell 1.0?
на счет версии сказать не могу, использую ПоШ из семерки ,это второй.
Для передачи параметров из командной строки, если правильно понял. Замените шапку скрипта на :
В результате скрипт можно запускать с двумя параметрами, к пример так: Строку $Dest1ToDest2= $File.FullName.Replace($Dest1, $Dest2)
можно попробовать на что-то заменить. Суть ее такова, что в $File.FullName (содержащей полный путь до адреса) $Dest1 заменяется на $Dest2.
я знаю как задавать параметры, но почему срока $Dest1ToDest2= $File.FullName.Replace($Dest1, $Dest2), не хочет работать с переменными а только работает если задать вместо перменных ":\1' и ":\"?
вот как у вас :
$Dest1ToDest2= $File.FullName.Replace($Dest1, $Dest2),
а у меня только так работает:
$Dest1ToDest2= $File.FullName.Replace(":\1", ":\2"),
и получается что при определении переменных dest1 dest2 как параметры все равно необходимо влазить в скрипт переправлять эту строчку вручную.
а назначить в переменную ":\1" нельзя.
в cmd есть команда net use а в ПОШ какая ей аналогичная?
Хм. Первое. что пришло в голову , у вас же Active Directory, запускайте скрипт от имени пользователя, у которого есть нужные права.
Скрипт выполняется из scheduler`а ?
Ну это все сложно получается.
Нужно разработать логику поведения.
Мое видение этой проблемы будет решаться скриптом + шедулером. Проще будет подключить на компе, с которого запускается скрипт, сетевой диск. И не отключать его.
По поводу тайм-аутов и прочего. Поставьте в шедулере повторение каждые 15 минут. И не отлавливать недоступность хоста. А просто не выполнять весь цикл скрипта. запускайте от имени,кто имеет привелегии на сетевой папке.
$DestCompName = "srv017" новый параметр, имя компа, с которым нужно синхронизироваться.
$Dest1ToDest2= $File.FullName.Replace($Dest1, $Dest2)
Write-host "Обрабатываю" $File.fullname $File.LastWriteTime
Что-то беда какая-то при передачи параметров, тогда не отрабатывает строка
$Dest1ToDest2= $File.FullName.Replace($Dest1, $Dest2)
Необходимо, чтобы ASP скрипт копировал шаблон и вставлял в некоторые места документа мои значения
У меня есть некий шаблон документов, мне необходимо, чтобы ASP скрипт копировал этот шаблон и.
Как сделать скрипт, который бы копировал файлы?
Есть файлы, которые надо вставить в определённое место. Для этого надо написать скрипт, который бы.
Как сделать так, чтобы bat-файл копировал сам себя в папку N-ное количество раз?
Добрый день! Как сделать так чтобы bat файл копировал сам себя в папку N колличество раз?
Как сделать чтобы макрос искал в столбце любой знак и если находил копировал строку на другую страницу с вставкой строки?
Блин, как сделать чтобы макрос искал в столбце любой знак и если находил копировал строку на другую.
я, если честно, не понял смысла задания, но если читать дословно, то вот некоторые советы:
1. на мой взгляд лучше использовать цикл dowhile (условие) и убрать всякие $k++
2. в цикле идет проверка test-path $path1 - если действительно нужно так проверять, то нужно проверить test-path $path1+"имя копируемого файла", ато здесь идет проверка на существование папки, в которую происходит копирование
3. возможно границы заданы неправильно, я менял gt и lt местами, файлы находились
Выбрать случайную папку, скопировать из неё все файлы и перенести в другую папку
Добрый день! Прошу помощи в написании батника. Имеется папка A с неким количеством других папок.
Выбрать случайную папку, скопировать из неё все файлы и перенести в другую папку
Добрый день! Прошу помощи в написании скрипта. Имеется папка A с неким количеством других папок.
Найти файлы с определенной датой
Извлекаю дату в текстбокс я значит из календаря textBox1.Text = e.End.ToString("dd/MM/yyyy"); Как.
Скрипт переноса файла в новую папку с датой
Помогите написать скрипт для cron. Есть папка в ней файлы,нужно каждый день вырезать с этой папки.
Читайте также: