There is a script on powershell, which from one directory selects the last file there (namely, the database backup) copies it to the local disk (as the backup is on another machine on the network) and restores the backup to the test database. Everything works well, but there is one thing, if in some way a file other than a backup gets into the source folder and it turns out to be the last one, then the script takes and copies it. In general, everything is logical what I wanted, but I would like the script to select the latter only among backups, that is, files with the * .bak extension. Here is an example of the script itself.

[CmdletBinding()] Param([string] [Parameter(Mandatory=$true)] $SqlServer=$null, # SQL Сервер для которого будет исполняться скрипт [Parameter(Mandatory=$true)] $SqlBaseConnect=$null, # База данных к которой будем подклюдчаться [Parameter(Mandatory=$true)] $SqlBaseRestore=$null, # База данных для которой будет исполняться скрипт [Parameter(Mandatory=$true)] $SqlLogin=$null, # Логин базы данных [Parameter(Mandatory=$true)] $SqlPassw=$null, # Пароль базы данных [Parameter(Mandatory=$true)] $destination=$null, # Каталог назначения [Parameter(Mandatory=$true)] $DiskSource=$null, # Диск источника [Parameter(Mandatory=$true)] $CatalogSource=$null) # Каталог источника #Запуск таймера $watch = [System.Diagnostics.Stopwatch]::StartNew() $watch.Start() #Лог скрипта $LogF="RestoreBackupLog.txt" if (Test-Path $LogF) {Clear-Content $LogF} Add-Content -Path $LogF -Value "Starting ..." # Переприсваиваем переменную источника к виду Путь источника $Source=$DiskSource+$CatalogSource # Проверяем существует ли источник $TestPasth = Test-Path $Source if ($TestPasth -eq "True") { # Выбираем самый новый файл на источнике. $FileCopy = Get-ChildItem -Path $Source -ErrorAction SilentlyContinue -ErrorVariable ErrVarFile | Sort-Object LastWriteTime | Select-Object -Last 1 } else {Write-Host Указаный путь не существует exit} # Копируем выбраный фаил Copy-Item -Path "$Source\$FileCopy" -Destination "$destination" -Force -ErrorAction SilentlyContinue -ErrorVariable ErrVar | Out-Null $ErrVarStd=$? Add-Content -Path $LogF -Value $ErrVar # Проверяем скопировался ли фаил, если да то запускам востановлние базы if ($ErrVarStd -eq "True") { #Подключение к SQL и выполнение запроса $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server=$SqlServer; Database=$SqlBaseConnect; User ID=$SqlLogin; Password=$SqlPassw;" $SqlConnection.Open() $SqlCmd = $SqlConnection.CreateCommand() $SqlCmd.CommandText = "Restore database [$SqlBaseRestore] FROM DISK = '$destination\$FileCopy'" $objReader = $SqlCmd.ExecuteReader() while ($objReader.read()) { Write-Output $objReader.GetValue(0) } $objReader.close() # Удаляем фаил бэкапа из каталога назначения после востановления Remove-Item $destination\$FileCopy } else {Write-Host Не удалось скопировать фаил бэкапа exit } #Остановка таймера $watch.Stop() $elapsedtime=$watch.Elapsed Write-Host Время выполнения $elapsedtime Add-Content -Path $LogF -Value "Время выполнения $elapsedtime" 

If you change the line to mind

 $FileCopy = Get-ChildItem -Path $Source -Include *.bak -ErrorAction SilentlyContinue -ErrorVariable ErrVarFile | Sort-Object LastWriteTime | Select-Object -Last 1 

Then the script stops working, since the $ FileCopy variable takes the form of a full path to the file, but even if the line is replaced

 Copy-Item -Path "$Source\$FileCopy" 

on

 Copy-Item -Path "$FileCopy" 

The script at the destination creates a folder instead of a file and, respectively, falls without finding the file. Tell me how you can select exactly the backup files from the target directory.

  • Rewrite the copy so $FileCopy | Copy-Item -Destination "$destination" ... $FileCopy | Copy-Item -Destination "$destination" ... , or so Copy-Item -Path $FileCopy.FullName -Destination "$destination" ... - Andrei Odegov

1 answer 1

In fact, everything was decided a little differently. At the weekend, reading the monoals)))) namely how the Get-ChildItem workslet turned out that you just need to use the -Filter parameter instead of the -Include parameter and everything works fine. All because the value of the -Include parameter must include all elements, including the directory in which the search is performed. When using -Filter, the results are filtered directly in the process of retrieving data (folders and files), and -Include and -Exclude are applied after all data has been received. That's actually the solution.