butenin.ru

... non penis canina est!

Аналог Zalman ZM-VE300

Так как теперь в продаже не отыскать Zalman ZM-VE300, а новая модель ZM-VE350 гораздо хуже, лучше купить IODD-2531. Ничем не отличается от оригинального бокса от Zalman, прошивки взаимозаменяемы. Стоимость в даный момент на AliExpress – чуть менее 3000 руб.

Microsoft Security Essentials и OOBE

Чтобы MSE остался в том же виде, что и перед отработкой sysprep, нужно поменять в реестре параметр HKLM\SOFTWARE\Microsoft\Microsoft Security Client\OOBE на 0.

Например, так:

unattend.xml
1
2
3
4
5
6
7
8
9
10
11
<settings pass="specialize">
  <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <RunSynchronous>
      <RunSynchronousCommand wcm:action="add">
        <Description>Prevent MSE reinstall</Description>
        <Order>1</Order>
        <Path>cmd.exe /c reg.exe add &quot;HKLM\SOFTWARE\Microsoft\Microsoft Security Client&quot; /v OOBE /t REG_DWORD /d 0 /f /reg:64</Path>
      </RunSynchronousCommand>
    </RunSynchronous>
  </component>
</settings>

Копирование файлов

Оказывается, можно так:

1
2
3
$source = "Microsoft.PowerShell.Core\FileSystem::\\host1\share\file.ext"
$target = "Microsoft.PowerShell.Core\FileSystem::\\host2\share"
Copy-Item -Path $source -Destination $target

Вообще, многовато в PS геморроя с UNC-путями в недоменной среде.

Параметры в ScriptBlock

Часто нужно передать параметры в ScriptBlock в PowerShell. Возня с Param надоела, и был найден вот такой вариант:

1
2
3
4
5
6
$template = {
    MyVariable = "{MyVariable}"
    # ...
}

$scriptblock = [System.Management.Automation.ScriptBlock]::Create(($template | ForEach-Object { $_ -Replace "{MyVariable}", $MyOtherVariable }))

Мне это было удобно, когда использовались вложенные ScriptBlock-и – при создании задач планировщика на удалённом хосте.

Zabbix LLD и PowerShell

Чтобы с помощью PowerShell вывести список элементов для низкоуровневого обнаружения для Zabbix-а, удобно использовать подобную конструкцию:

mssql.discovery.ps1
1
2
3
4
$MSSQLDatabases = @{ data = @(); }
Set-Location "SQLSERVER:\SQL\localhost\DEFAULT\Databases"
$MSSQLDatabases.data = Get-ChildItem -Force | Select-Object -Property @{Name="{#MSSQLDATABASE}"; Expression = {$_.Name}}
$MSSQLDatabases | ConvertTo-Json

На выходе будет JSON нужного нам вида:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
    "data":  [
                 {
                     "{#MSSQLDATABASE}":  "master"
                 },
                 {
                     "{#MSSQLDATABASE}":  "model"
                 },
                 {
                     "{#MSSQLDATABASE}":  "msdb"
                 },
                 {
                     "{#MSSQLDATABASE}":  "tempdb"
                 }
             ]
}

Пользовательские параметры Zabbix Agent в Windows и кодировка

Предположим, на каком-то сервере с Windows у нас установлен Zabbix Agent, при этом настроен такой пользовательский параметр:

1
UserParameter=UserParameter,C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -NonInteractive -File "C:\Scripts\script.ps1"

Скрипт script.ps1 отдаёт строковое значение, да ещё и на русском:

script.ps1
1
Write-Host "Значение пользовательского параметра"

Если попробовать получить значение параметра с сервера, возникает проблема:

1
2
$ zabbix_get -s example.com -k UserParameter
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

Причина в том, что наш скрипт на PowerShell выдаёт значение в кодировке консоли – CP866, а нужно – в UTF8. Меняем скрипт:

script.ps1
1
2
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::WriteLine("Значение пользовательского параметра")

Проверяем:

1
2
$ zabbix_get -s example.com -k UserParameter
Значение пользовательского параметра

Свой KMS-сервер

Требования: питон 2.6 или 2.7, python-argparse (в 2.7 идёт в комплекте), python-tz (для локального времени в выводе скрипта).

Первым делом идём сюда, далее по ссылкам. Скачиваем py-kms_2014-01-03T032458Z.zip или более поздний вариант. Кладём его на сервер, распаковываем в /usr/local/pykms.

В файле server.py в самом начале добавляем shebang:

server.py
1
#!/usr/bin/python

Создаём init-скрипт и сохраняем его как /etc/init.d/pykms:

/etc/init.d/pykms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/sh

### BEGIN INIT INFO
# Provides:          myservice
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Put a short description of the service here
# Description:       Put a long description of the service here
### END INIT INFO

DIR=/usr/local/pykms
DAEMON=$DIR/server.py
DAEMON_NAME=PyKMS

DAEMON_USER=root

PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
  log_daemon_msg "Starting system $DAEMON_NAME daemon"
  start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON
  log_end_msg $?
}

do_stop () {
  log_daemon_msg "Stopping system $DAEMON_NAME daemon"
  start-stop-daemon --stop --pidfile $PIDFILE --retry 10
  log_end_msg $?
}

case "$1" in

  start|stop)
      do_${1}
      ;;

  restart|reload|force-reload)
      do_stop
      do_start
      ;;

  status)
      status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
  ;;

  *)
      echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
      exit 1
  ;;
esac

exit 0

Делаем эти файлы исполняемыми и добавляем к уровням запуска по умолчанию:

1
2
3
chmod +x /usr/local/pykms/server.py
chmod +x /etc/init.d/pykms
update-rc.d pykms defaults

P.S. PyKMS на данный момент не умеет писать логи, работа с SQLite тоже под вопросом.

Разные полезности для Oracle

Размер схем:

1
2
set pagesize 50000
select owner, sum(bytes) / 1024 / 1024 / 1024 tsize from dba_segments group by owner order by tsize desc;

Текущие коннекты:

1
echo 'SELECT username FROM v$session WHERE username IS NOT NULL ORDER BY username ASC;' | sqlplus SYS/oracle as SYSDBA

Извращения с подключением:

1
expdp \"SYS/oracle@host/orcl as SYSDBA\" directory=DUMPS dumpfile=FULL.DMP FULL=Y

Создание пользователя Oracle

Поменять NEW_USER_NAME и NEW_USER_PASSWORD.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- DROP USER NEW_USER_NAME CASCADE;

CREATE USER NEW_USER_NAME IDENTIFIED BY "NEW_USER_PASSWORD"
 DEFAULT TABLESPACE "USERS"
 TEMPORARY TABLESPACE "TEMP"
 QUOTA UNLIMITED ON "USERS";

GRANT ALTER ANY PROCEDURE TO NEW_USER_NAME;
GRANT ALTER ANY TABLE TO NEW_USER_NAME;
GRANT ALTER ANY TRIGGER TO NEW_USER_NAME;
GRANT ALTER PROFILE TO NEW_USER_NAME;
GRANT CREATE PROCEDURE TO NEW_USER_NAME;
GRANT CREATE SEQUENCE TO NEW_USER_NAME;
GRANT CREATE SESSION TO NEW_USER_NAME;
GRANT CREATE TABLE TO NEW_USER_NAME;
GRANT CREATE TRIGGER TO NEW_USER_NAME;
GRANT CREATE VIEW TO NEW_USER_NAME;
GRANT DELETE ANY TABLE TO NEW_USER_NAME;
GRANT DROP ANY PROCEDURE TO NEW_USER_NAME;
GRANT DROP ANY TABLE TO NEW_USER_NAME;
GRANT DROP ANY TRIGGER TO NEW_USER_NAME;
GRANT DROP ANY VIEW TO NEW_USER_NAME;
GRANT DROP PROFILE TO NEW_USER_NAME;

GRANT "CONNECT" TO NEW_USER_NAME;
ALTER USER NEW_USER_NAME DEFAULT ROLE ALL;