Ищем папки куда у нас нету доступа

4 Февраль 2010

Продолжаю выполнение чужих просьб :) В этот раз попросили сделать следующее. Есть файловый сервер и на нем бордак с правами и наследование отсутствует. Нужно найти все папки где в пермишенах нету определенной группы/пользователя. Во время написания скрипта обнаружилось две проблемы. Первая заключалась в том, что нашлись папки куда у администратора вообще доступа не было. Так же нашлись папки с путем больше 256 символов. По этому был добавлен обработчик ошибок который проблемные папки выводит в два файлика для дальнейшего разбирательства. Вот собственно и сама функция:

Function Get-NotPermissions ($path,$group,$error_rights,$error_long) {
#--- очищаем лог ошибок
    $error.Clear |out-null
#--- рекурсивно перебираем все папки
    foreach ($item in Get-ChildItem -LiteralPath $path -Recurse -Force -ErrorAction  SilentlyContinue -ErrorVariable error_mass | Where-Object {$_.PSIsContainer}) {
#--- создаем массив с разрешениями
        $groups = ($item.PSPath |get-acl).Access | select -expandproperty IdentityReference
#--- проверяем есть ли в массиве интересующая нас группа
        if ($groups -notcontains $group) { '"'+$item.fullname+'"'}
    }
   
#--- проверяем существует ли файл и если чего удаляем его
    if (Test-Path $error_rights) {Remove-Item -Path $error_rights -Force -Confirm}
    if (Test-Path $error_long) {Remove-Item -Path $error_long -Force -Confirm}
   
#--- обрабатываем полученные ошибки
    foreach ($item in $error_mass ) {
#--- нету доступа
        if ($item.CategoryInfo.Reason -eq 'UnauthorizedAccessException') {
            '"' + $item.TargetObject + '"'  |Out-File -Encoding 'Unicode' -FilePath $error_rights -Append
        }
#--- длинный путь, больше 256 символов
        elseif ($item.CategoryInfo.Reason -eq 'PathTooLongException') {
            '"' + $item.TargetObject + '"'  |Out-File -Encoding 'Unicode' -FilePath $error_long -Append
        }
    }
}

Ну и конечно пример запуска:

Get-NotPermissions -path '\\titan\C$\Bin\tmp' -group 'isea\abigor' -error_rights 'D:\error_NTFS.txt' -error_long 'D:\error_long_NTFS.txt'

Скрипт создания архива конфигурационных файлов FreeBSD сервера

20 Январь 2010

Продолжаю автоматизировать работу сервера. В этот раз руки коснулись автоматизации создания архива с конфигурационными файлами. При этом задачи были поставлены следующие:
1. Пути для архивации должны лежать в отдельном файле.
2. Архивироваться должен на сетевой ресурс расшаренный под Windows Server. При этом во время архивирования он должен подключаться, а по окончании отключаться.
3. Архивы должны создавать раз в день/неделю/месяц (тут я добавил от себя, архивы будут хранится с одной ротацией)

Для написания был выбран perl и в итоге получился вот такой скрипт:

#!/usr/bin/perl

#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2010.01.20
#   Description:    Скрипт скрипт создания архива конфигурационных файлов
#########################################################################################


#--- основные переменные
$dst = '/var/files/backup_nt/GW-01';
$dst_local = '/var/files/backup/config';
$mount_path = '/var/files/backup_nt';
chop($hostname = `hostname`);
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
$year += 1900;
$mon += 1;


#--- преобразовываем формат даты с 1 на 01
sub setformatnumber {
    if ($_[0] < 10 ) { return '0'.$_[0] }
    else { return $_[0] }
}

#--- проверка подмонтирования директории для архивов
if (!`df -Hac | grep backup_nt`) {
    system("mount $mount_path")
}

#--- проверяем на всякий случай доступность пути
if ( -d $dst ) {
#--- создаем список что архивировать
    open(list,"/root/list/backup_list");
    while($in=<list>) {
        $in=~s/\s$//;
        $what_backup=$what_backup." ".$in;
    }

#--- создаем дневной архив
    $to_backup = "$dst/day/$year-".setformatnumber($mon)."-".setformatnumber($mday).".day.$hostname.backup.config.tar.bz2";
    system("/usr/bin/tar jvcf $to_backup $what_backup");

#--- удаляем старые дневные архивы
    $rm_backup = "$dst/day/$year-".setformatnumber($mon)."-".setformatnumber($mday-2).".day.$hostname.backup.config.tar.bz2";
    if ( -e $rm_backup) {
        system ("/bin/rm -f $rm_backup");
    }

#--- создаем бак за месяц
    if ($mday eq 1 ) {
        $to_backup = "$dst/month/$year-".setformatnumber($mon)."-".setformatnumber($mday).".month.$hostname.backup.config.tar.bz2";
        system("/usr/bin/tar jvcf $to_backup $what_backup");

#--- удаляем старые месячные архивы
        $rm_backup = "$dst/month/$year-".setformatnumber($mon-2)."-".setformatnumber($mday).".day.$hostname.backup.config.tar.bz2";
        if ( -e $rm_backup ) {
            system ("/bin/rm -f $rm_backup");
        }
    }
#--- создаем недельный архив
    if ((localtime(time))[6] eq 1 ) {
        $to_backup = "$dst/week/$year-".setformatnumber($mon)."-".setformatnumber($mday).".week.$hostname.backup.config.tar.bz2";
        system("/usr/bin/tar jvcf $to_backup $what_backup");

#--- удаляем старые недельные архивы
        $rm_backup = "$dst/week/$year-".setformatnumber($mon)."-".setformatnumber($mday-14).".week.$hostname.backup.config.tar.bz2";
        if ( -e $rm_backup ) {
            system ("/bin/rm -f $rm_backup");
        }
    }
}

#--- после завершения бекапа отмонтируем директорию
if (`df -Hac | grep backup_nt`) {
    system("umount $mount_path")
}

Файл /root/list/backup_list выглядит следующим образом:

[root@gw-01 bin]# cat /root/list/backup_list
/boot
/etc
/root
/usr/local/etc
/var/named
/var/cron/tabs/root
[root@gw-01 bin]#

Скрипт геренации статистики squid

15 Январь 2010

Заказчик заказал чтоб логи каждый день создавалась по следующими свойству, каждые 24 часов за прошлый день и ложись в пути ${dst}/2010/01/14 и в каждого первого числа создавалась за месяц по адресу ${dst}/2010/01/month. Было принято решение написать не большой sh скрипт и поместить его в cron

#!/bin/sh
#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2010.01.16
#   Description:    Скрипт генерации статистики squid по средствам sarg
#########################################################################################

#--- основные переменные
dst='/usr/local/www/data/stat'
sarg='/usr/local/bin/sarg'
create_dir='/bin/mkdir -p'
ddate='/bin/date'
check=0

#--- переменные для дат
current_month_number=`${ddate} "+%m"`
last_month_number=${current_month_number}

current_year_number=`${ddate} "+%y"`
last_year_number=${current_year_number}

current_day_number=`${ddate} "+%d"`
last_day_number=${current_day_number}

#--- составляем основотую команду
command="${ddate} -v${current_day_number}d -v${last_month_number}m -v${last_year_number}y -v-1d "

#--- если сегодня 2010.01.01
if ([ `${ddate} +%m`  -eq 1 ] && [ `${ddate} +%d` -eq 1 ])
then
    ${create_dir} ${dst}/`$command +%Y`/`$command +%m`/"month"
    ${sarg} -d 01/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
    ${create_dir} ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
    ${sarg} -d `$command +%d`/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
    check=1
#--- если сегодня первое число любого месяца кроме января
elif ([ `${ddate} +%d`  -eq 1 ] && [ ${check} -ne 1 ] && [ `${ddate} +%m` -ne 1 ])
then
    ${create_dir} ${dst}/`$command +%Y`/`$command +%m`/month
    ${sarg} -d 01/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
    ${create_dir} ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
    ${sarg} -d `$command +%d`/`$command +%m`/`$command +%Y`-`$command +%d`/`$command +%m`/`$command +%Y` -o ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
#--- любое число кроме 1
elif [ `${ddate} +%d` -ne 1 ]
    then
    ${create_dir} ${dst}/`$command +%Y`/`$command +%m`/`$command +%d`
    ${sarg} -d `${ddate} -v-1d +%d/%m/%Y`-`${ddate} -v-1d +%d/%m/%Y` -o ${dst}/`${command} +%Y`/`${command} +%m`/`${command} +%d`
fi

Функция поиска старых файлов

14 Январь 2010

Попросили у меня совета как можно найти в папке созданные 10 дней назад файлы и удалить их. Подумав у меня родилась вот такая простенькая функция:

Function Search-OldFiles  {
    param ($day,$path,[switch]$search)

    $help = @"
`n
`t Надо использовать следующий синтаксис функции:
`t -day - задаем кол-во дней
`t -path - указываем путь
`t -search - указываем, что необходимо только найти файлы (по умолчанию они удаляются)
`t------------------------------------------------------------------------------------
`t Пример:
`t Search-OldFiles -day 2 -path 'D:\Games' -search
"
@
#--- проверяем существование параметров функции
    if (!($day) -or !($path) ) {write-warning $help; return}
#--- рукурсивно просматриваем папки и выбираем файлы 
    foreach ($item in Get-ChildItem -LiteralPath $path -Recurse -Force | Where-Object {!$_.PSIsContainer}) {
#--- сравниваем дату создания файла
        if ((Get-Date).adddays(-$day) -ge $item.CreationTime)  {
#--- в зависимости от ключа search просто ищем или удаляем      
            if ($search) { '"' + $item.fullname + '"' }
            else { $item.fullname | Remove-Item -Force -WhatIf }
        }
    }
}

Функция для работы с MySQL

13 Январь 2010

Начнем с MySQL. С ним оказалось не все так просто. Для работы с ним необходимо на компьютер где будет работать функция/скрипт установить Connector/Net от MySQL соответствующий версии вашего сервера. Прочитав доку в общем получается одна функция для select/inserd/delete/update.

Function Connect-ToMySQL {
    param([String]$query,[String]$database,[String]$hostmysql,[String]$login,[String]$password)
#--- загрудаем компоненты mysql
    [void][system.reflection.Assembly]::LoadWithPartialName("MySql.Data")
#--- открываем подключение
    $connStr = "server=$hostmysql;port=3306;uid=$login;pwd=$password;database=$database;Pooling=False"
    $conn = New-Object MySql.Data.MySqlClient.MySqlConnection($connStr)
    $conn.Open()
#--- создаем объекты для выполнения запроса
    $cmd = New-Object MySql.Data.MySqlClient.MySqlCommand($query, $conn)
    $da = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($cmd)
    $ds = New-Object System.Data.DataSet
#--- получение запроса
    $da.Fill($ds) | Out-Null
#--- ну и вывод на экран
    $ds.Tables[0]
#--- закрываем подключени
    $conn.close()
}

В итоге получаем вот такой результат:

[PS] <16> C:\Bin>$inquiry = 'SELECT  `domain-id`,username,active FROM users WHERE username="abigor@isea.ru"'
[PS] <17> C:\Bin>Connect-ToMySQL -database 'mail-server' -login 'usertest' -password 'pass' -hostmysql 'sqlsrv' -query $inquiry

domain-id   username    active
---------   --------    ------
1       abigor@isea.ru  true

[PS] <18> C:\Bin>
[PS] <18> C:\Bin>$inquiry = 'update users set active="false" WHERE username="abigor@isea.ru"'
[PS] <19> C:\Bin>Connect-ToMySQL -database 'mail-server' -login 'usertest' -password 'pass' -hostmysql 'sqlsrv' -query $inquiry

[PS] <20> C:\Bin>$inquiry = 'SELECT  `domain-id`,username,active FROM users WHERE username="abigor@isea.ru"'
[PS] <21> C:\Bin>Connect-ToMySQL -database 'mail-server' -login 'usertest' -password 'pass' -hostmysql 'sqlsrv' -query $inquiry

 domain-id  username    active
 ---------  --------    ------
 1      abigor@isea.ru  false

[PS] <22> C:\Bin>

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

`domain-id`

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

``domain-id``

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

Десятая встреча MCP клуба

25 Декабрь 2009

На десятой (2009.12.24) юбилейной для нас встрече я был докладчиком на тему «System Center Configuration Manager и инвентаризация на предприятии». Все прошло отлично. Для себя я понял, что второй мой доклад прошел уже на много лучше, не смотря на то что я готовился к нему в последние дни, тут я уже рассказывал более спокойнее, увереннее и меньше запинался. Волнения почти не было. Единственный минус какой был, я не все смог реализовать на стенде и по этому не все показал, но максимально постарался про это рассказать. Жаль конечно, но в этом я виноват опять же сам, так как готовился по свой привычке в последний день :)
Так же выкладываю свою презентацию. Хотя она конечно не на столь крутая как первая, но думаю может кому пригодится.

Author: abigor Categories: Новости, Саморазвитие Tags:

Microsoft Certified Professional

14 Ноябрь 2009

Всем привет, вчера 13.11.09 в 13.00 по иркутскому времени я стал Microsoft Certified Professional он же MCP в простонародье. Добиться этого я смог сдав экзамен 70-290. Сегодня я получил два письма из которых я узнал свой MCP ID под номером 7215719 :) и код активации.
Зарегистрировавшись на https://mcp.microsoft.com/mcp я узнал страшную для себя новость :( Она заключается в том, что бумажные сертификаты теперь не высылаются, пластиковые карты отменили. Бумажный сертификат правда все еще можно заказать, что я и сделал.
Теперь готовлюсь к следующему экзамену. Надеюсь так же сдать его с положительным результатом.

Author: abigor Categories: Саморазвитие Tags:

Домены третьего уровня для mcp-клуба

11 Ноябрь 2009

Для нашего mcp-клуба были приобретены два домена mcp.irk.ru и mcp-club.irk.ru чтоб мы могли создать собственный портал для нашего клуба на котором IT-специалисты смогут общаться. Так же есть для нашего клуба практические не ограниченная техническая площадка. Хотя на данный момент народ особо сильно не понимает для чего это нужно. Я думаю для нас это большой шаг в развитии. Это нам позволит создать собственный форум для обсуждения клубных и технических тем. Размещать тематические статьи написанные участниками клуба. Обсуждать доклады клуба, так же их планировать. Так как если честно у нас нету резерва в докладах. Пока мы находимся в зачаточном периоде развития. Хотя мы уже провели восемь встреч. Вроде определились с организатором, с участниками. Но пока мы как новорожденные котята, слепы и постоянно ищем мамку :) Если честно, я пока не понимаю, но мне почему-то хочется из нашего клуба сделать самый крупный клуб на территории Сибири! Кто знает. Может это и получится сделать.

Author: abigor Categories: Новости Tags:

Перенос WSUS сервера на другой сервер.

9 Ноябрь 2009

Попросил меня тут товарищ развернуть сервер WSUS у него на халтуре по средством копирования скаченного контента на моей работе, так как у него трафик платный, а за раз утянуть 17-20 гигов у него нету возможности. По этому он обратился ко мне за помощью. Первой же мыслю как это не странно было зайти на technet. Там как раз оказалась дока на тему: «как провести синхронизацию между двумя WSUS серверами без сетевого подключения». В этом случаи все оказалось достаточно просто. Для этого нужно воспользоваться имеющийся в комплекте утилитой. По этому опишу ход действий:

1. cd "C:\Program Files\Update Services\Tools"
2. wsusutil.exe export export.cab export.log (Экспортирует метаданные обновления (но не файлы содержимого, одобрения
или параметры сервера) в файл экспортного пакета.)
этого пакета на другой WSUS-сервер позволяет выполнить синхронизацию
3. Создаем бекап папки где лежит сам скаченный контент
4. На новом сервере устанавливаем новый WSUS сервер, пропускаю запрос мастера на настройку.
5. Разворачиваем бекам в папку с контентом нового WSUS, не забываем поправить права если просто копировали.
6. wsusutil.exe import export.cab export.log (Импортирует метаданные обновления (но не файлы содержимого, одобрения
или параметры сервера) на этот сервер.)
7. Дальше запускаем оснастку WSUS и настраиваем что вам необходимо

Вот в общем и все. В итоге мы получили сервер скажем в филиале, где не надо скачивать по новой все 17-20 гигов обновлений.
В общем все хорошо, но тут у меня появилась мысль, а не перенести ли наш корпоративный сервер в виртуальную машину на Hyper-V раз такая пьянка пошла. Только вот не хочется опять ждать присоединения всех машин в сети и по новой тыкать одобрения. Начал по этому искать выход. Он оказался достаточно простой:

1. На новом сервере устанавливаем WSUS и так же отказываемся от мастера.
2. С помощью SQL Server Management Studio делаем бекап базы и логов на основном сервере.
3. Остановив службу Update services на исходном сервере, копируем скаченный контент на целевой сервер
и кладем куда следует. Так же не забываем про права и про то, что на целевом сервере служба Update services
так же должна быть выключена.
4. Импортируем новую базу SUSM
5. Запускаем службу Update services на целевом сервере
6. Если папка с обновления на целевом сервере совпадает с местом на исходном, то ни чего делать не надо,
если нет, то командуем wsusutil movecontent "D:\WSUS Updates" -skipcopy (Вот тут странно как-то получилось. Когда я
пробовал так сказать на кошках. У меня не заработала без этого. А когда уже все переносил все подхватилось само.)
7. wsusutil reset

После этого можно запустить оснастку управления WSUS сервером и у вас должна получиться копия исходного сервера.

Так же последний, и думаю самый правильный способ. Это сделать следующее. Открыть оснастку WSUS открыть «Параметры -> Источник обновлений и прокси-сервер». Установить переключатель в «Синхронизировать с другим сервером Windows Server Update Services», указать старый исходный сервер, и установить флажок «Данный сервер является репликой вышестоящего сервер» После репликации возвращаем флаг на «Синхронизировать с центром обновления Microsoft»

Вот такими путями можно переносить wsus сервер. Если я где-то не прав или допустил не точности, прошу поправить в комментариях.

Author: abigor Categories: Работа, Саморазвитие Tags:

Скрипт бекапа сайтов на web сервере

8 Октябрь 2009

Захотелось автоматизировать создание баков на веб сервере. Для этого у всех учеток изменил описание на hosting, что можно было всех махом выдернуть из /etc/passwd. В итоге получился такой скрипт который не зависит от вновь заведенных сайтов. Он сам обработает новых товарищей.

#!/bin/sh
#########################################################################################
#   Created:        Zakharchenko Andrey Ruslanovich
#   Date:           2009.09.16
#   Description:    Скрипт создания резервных копий сайтов отдельными арховами
#########################################################################################

#--- приветствие так сказать
/bin/echo "1. Backup hosting folders start. Time start: `/bin/date +%Y:%m:%d:%H:%M:%S`"
/bin/echo ""
#--- цикле перебираем /etc/passwd и получаем путь до домашних папок
for i in `cat /etc/passwd |awk -F: '$5~"hosting" {print($6)}'`;
#--- создаем целевую папку для архивов
do mkdir -p /var/files/backups/hosting/`date +%Y/%m/%d`&& \
#--- выводим информацию о том какой сайт архивируется и когда начал архивироваться
    /bin/echo "Backup hosting folders: `/bin/echo $i`  start. Time start: `/bin/date +%Y:%m:%d:%H:%M:%S`" && \
#--- список исключений которые не попадут в архив
    tar --exclude *access.log --exclude *error.log --exclude tmp --exclude php-cgi.core \
#--- ну и собственно чего архивируем и куда кладем
    -cjf /var/files/backups/hosting/`date +%Y/%m/%d`/`date +%Y.%m.%d.%H%M`-`\
    echo $i |awk -F '/' '{print($5)}'`.tar.bz2 $i;
done

Вот такой получился маленький и удобный скриптец :)