Так пришла идея создать удобный и контролируемый сервис для пересылки больших файлов в локальной сети.
Реализация на PowerShell, платформа Windows.
Требования:
- Веб сервер опубликованный в интернет.
- Расшаренная папка на компьютере под Windows (для определения владельца файла).
- Настройка на сервере с шарой выполнения скрипта по расписанию, раз в минуту.
Как это работает:
- Пользователь помещает ZIP архив в расшаренную папку на сервере.
- Скрипт ищет ZIP-файлы в расшаренной папке и перемещает их в папку веб-сервера, затем отправляет письмо Владельцу файла.
- Пользователю приходит письмо со ссылкой на скачивание файла через ваш веб-сервер.
- Пользователь пересылает письмо со ссылкой на скачивание адресату.
Описание работы скрипта:
- Удаление в целевой папке всего, что не имеет расширения ZIP.
- Получение списка ZIP-файлов в целевой папке.
- Перебор ZIP файлов с обработкой каждого файла функцией Send_URL.
- Функция Send_URL: определяет Владельца файла, обрабатывает имя файла, перемещает файл под новым именем в папку веб-сервера, высылает Владельцу и Администратору (для контроля) на почту ссылку на скачивание файла, удаляет файлы в папке веб-сервера старше определенного количества дней. Более подробные комментарии смотрите в скрипте.
- Создание файла в расшаренной папке с именем-подсказкой «только ZIP архив, остальное удаляется.txt».
Примечание: если пользователь входит в группу Администраторы на сервере с расшаренной папкой, то Владелец = группе Администраторы, для этого в скрипте указывается административный почтовый ящик.
В скрипте необходимо поменять следующие параметры на требуемые вам:
$path = "C:\UPLOAD\" #Расшареная папка на сервере
$path1 = "C:\inetpub\wwwroot\UPLOAD\" #Папка на веб-сервере, откуда скачивают
В функции Send_URL изменить параметры:
$day = -30 #Вы можете скачать файл в течении "+(-1*$day)+" дней. Затем файл будет удален с сервера.
$mail_domain = "@mydomain.com"
$owner_domain = "mydomain\\"
$mail_admin = "admin@mydomain.com"
$mail_server = "mail.mydomain.com"
$http = "http://web.mydomain.com/UPLOAD/"
Корректное определение владельца файла возможно только в домене. Без домена вам придется завести учетные записи пользователей на компьютере с расшаренной папкой и ассоциировать их с вашими пользователями.
Код:
#Файл Func.ps1 ###################################
# Смирнов Александр Николаевич hars@bk.ru декабрь 2015г.
Function Send_URL($File,$path,$path1){
### Параметры которые необходимо поправить на свои
##################################################
$day = -30 #Вы можете скачать файл в течении "+(-1*$day)+" дней. Затем файл будет удален с сервера.
$mail_domain = "@mydomain.com"
$owner_domain = "mydomain\\"
$mail_admin = "admin@mydomain.com"
$mail_server = "mail.mydomain.com"
$http = "http://web.mydomain.com/UPLOAD/"
##################################################
$File_nm = $File.Trim() # Удаление пробелов в начале и в конце в имени файла
$File = $File -replace '\[|\]','`$0' # Замена [] на корректные символы
$owner = ( Get-Acl ($path + $File) ).Owner # Владелец файла
############## Формирование email
if( $owner -like "*dministrator*" -or !$owner ){
$mail = $mail_admin
}else{
$mail = ($owner -ireplace($owner_domain,"")) + $mail_domain
}
######################################
#$md5 = Get-FileHash ($path + $File) -Algorithm MD5
#$File_url = $md5.Hash + ".zip"
#$File_new = $path1 + $md5.Hash + ".zip"
############# Ограничение размера имени файла
if($File_nm.length > 100){
$File_url = $File_nm.Substring(0,100)
}else{
$File_url = $File_nm
}
#############################################
############# Замена символов @!{}%$#''&`
$File_url = $File_url -ireplace("#","")
$File_url = $File_url -ireplace("%","")
$File_url = $File_url -ireplace("$","")
$File_url = $File_url -ireplace("&","_")
$File_url = $File_url -ireplace("{","(")
$File_url = $File_url -ireplace("}",")")
$File_url = $File_url -ireplace('`',"")
$File_url = $File_url -ireplace('"',"")
$File_url = $File_url -ireplace("'","")
$File_url = $File_url -ireplace("~","")
$File_url = $File_url -ireplace(" ","_")
#########################################
# Формирование имени файла для публикации в веб
$File_url = $mail + "_" + $File_url
# Путь перемещаемого файла
$File_new = $path1 + $File_url
# Перемещение файла в веб-папку
Move-Item -path ( $path + $File ) -destination $File_new -force -EA SilentlyContinue #-whatif
# Проверка перемещения файла на случай если он ещё копируется пользователем в папку
if( Get-ChildItem $File_new -EA SilentlyContinue){
write-host "OK" #Файл существует
}else{
write-host "NO" #Файл не сущетсвует
break # прерывание функции
}
# Размер файла
$colItems = (Get-ChildItem $File_new | Measure-Object -property length -sum)
$colSize = "{0:N2}" -f ($colItems.sum / 1MB) + " Mb"
######################################
#Сообщение пользователю
$Body = "<b>Скачать: </b><a href='" + $http + $File_url +"'>" + $File_nm + " (" + $colSize + ")</a><br/>
Вы можете скачать файл в течении "+(-1*$day)+" дней. Затем файл будет удален с сервера."
#Отправка письма
Send-MailMessage -to $mail -from $mail_admin -subject "Пересылка файлов" -BodyAsHtml $Body -Encoding UTF8 -SmtpServer $mail_server
#Отправка письма администратору, для контроля
if($mail -inotlike $mail_admin){
Send-MailMessage -to $mail_admin -from $mail -subject "Пересылка файлов" -BodyAsHtml $Body -Encoding UTF8 -SmtpServer $mail_server
}
Write-Host $owner $mail $Body # Проверка в консоли что кому отправляем
######################################
#Проверка устаревания файлов в веб-папке и их удаление по мере устаревания
get-childitem $path1 *.zip | where {$_.lastwritetime -le (get-date).adddays($day) } | del -Recurse -Force
}
##########################################################################################
##########################################################################################
##########################################################################################
##########################################################################################
##########################################################################################
#Файл Send_URL.ps1 ###################################
# Смирнов Александр Николаевич hars@bk.ru декабрь 2015г.
#В расписание добавить исполнение скрипта раз в минуту
# powershell.exe "C:\Scripts\Send_URL.ps1" -NoLogo -NonInteractive -WindowStyle Hidden
<#
."C:\scripts\Func.ps1" # Подгружаем файл с функциями. Лучше подгружать функции(процедуры), так красивее.
#>
### Параметры которые необходимо поправить на свои
##################################################
$path = "C:\UPLOAD\" #Расшареная папка на сервере
$path1 = "C:\inetpub\wwwroot\UPLOAD\" #Папка на веб-сервере, откуда скачивают
##################################################
# Удаляем все кроме ZIP файлов
Get-ChildItem $path -Recurse -Exclude *.zip | %{ Remove-Item $_ -Force -Recurse }
# Получаю имена файлов в папке
$flist = get-childitem $path"*.zip" #-recurse
# Перебор ZIP файлов, перемещение и отсылка владельцу файла письма со ссылкой
$flist | ForEach-Object{ Send_URL $_.PSChildName $path $path1 }
# Заново копируем html перенаправляющий на сайт
#В файле index.html строчка перенаправления, для "невозможности" просмотра папки в браузере
#<html><head><meta http-equiv="refresh" content="0;url=http://www.yandex.ru" /></head></html>
#copy C:\inetpub\wwwroot\index.html C:\inetpub\wwwroot\UPLOAD\index.html -Force
# Создание файла с именем-подсказкой, для особо одаренных
New-Item $path"только ZIP архив, остальное удаляется.txt" -type file -Force
Комментарии (10)
BoNi
06.02.2016 09:57Мысли у админов схожи, да и инструменты одни и те же…
Делал год назад — практически один в один с вашей (powershell, веб-сервер, письма шлем владельцу файла). Единственное серьезное отличие — папка не сканируется раз в минуту, а на нее вешается System.IO.FileSystemWatcher. И проблему с *dministrator* обходить не стал, лень было :)hlgroup
06.02.2016 10:46Согласен. Открытия тут никакого нет, но как ни крути для кого-то есть :)
zolti
07.02.2016 14:21а может есть смысл заставить скрипт создавать zip архивы, если пользователь сам не сумел этого сделать?
hlgroup
07.02.2016 17:34Тогда очень велика вероятность получения бардака. Пользователи в таком случае начнут «умничать»: создавать свои папки, а потом в них закидывать, то что им надо — соответственно надо будет выяснять в какой момент запускать скрипт. При срабатывании скрипта Пользователь начнет орать, что он ещё не дозакинул или ещё хуже при копировании папки или файлов у него вылезла ошибка типа «Длинные имена файлов» и т.п. — одни проблемы на пустом месте. Поэтому было принято решение, что пользователь закидывает в папку ZIP-архив, который потом сможет открыть любой адресат, даже без специальной программы.
В папку одновременно могут закинуть свои файлы несколько пользователей, а теперь представьте этот сценарий. А если 1 пользователь хочет отправить 2-3 разных папки разным адресатам и все это + то что написано чуть выше. Сложности возникающие при таких сценариях не стоят усилий по их преодолению.
Так что пусть пользователи «сумеют» создать ZIP-архив и закинуть в папку, но да такие «пользователи» в природе существуют.
click0
Попробуйте использовать вебсервер на nginx.
И сделать подчиненные nginx сервера с корнями в расшаренные папки.
А с основного вебсервера, через try_files опрашивать подчиненные сервера.