"
} | Out-File $path
Invoke-Item $path
```
### PSWriteHTML
```PowerShell
Import-Module PSWriteHTML
(Get-Module PSWriteHTML).ExportedCommands
Get-Service | Out-GridHtml -FilePath ~\Desktop\Get-Service-Out-GridHtml.html
```
### HtmlReport
```PowerShell
Import-Module HtmlReport
$topVM = ps | Sort PrivateMemorySize -Descending | Select -First 10 | %{,@(($_.ProcessName + " " + $_.Id), $_.PrivateMemorySize)}
$topCPU = ps | Sort CPU -Descending | Select -First 10 | %{,@(($_.ProcessName + " " + $_.Id), $_.CPU)}
New-Report -Title "Piggy Processes" -Input {
New-Chart Bar "Top VM Users" -input $topVm
New-Chart Column "Top CPU Overall" -input $topCPU
ps | Select ProcessName, Id, CPU, WorkingSet, *MemorySize | New-Table "All Processes"
} > ~\Desktop\Get-Process-HtmlReport.html
```
# SQLite
```PowerShell
$path = "$home\Documents\Get-Service.db"
$Module = Get-Module MySQLite
if ($Module -eq $null) {
Install-Module MySQLite -Repository PSGallery -Scope CurrentUser
}
Import-Module MySQLite
New-MySQLiteDB -Path $path # создать БД
Invoke-MySQLiteQuery -Path $path -Query "CREATE TABLE Service (Name TEXT NOT NULL, DisplayName TEXT NOT NULL, Status TEXT NOT NULL);" # создать таблицу
$Service = Get-Service | select Name,DisplayName,Status
foreach ($S in $Service) {
$Name = $S.Name
$DName = $S.DisplayName
$Status = $S.Status
Invoke-MySQLiteQuery -Path $path -Query "INSERT INTO Service (Name, DisplayName, Status) VALUES ('$Name', '$DName', '$Status');"
}
```
`(Get-MySQLiteDB $path).Tables` список таблиц в базе \
`Invoke-MySQLiteQuery -Path $path -Query "SELECT name FROM sqlite_master WHERE type='table';"` список таблиц в базе \
`Invoke-MySQLiteQuery -Path $path -Query "DROP TABLE Service;"` удалить таблицу
```PowerShell
$TableName = "Service"
Invoke-MySQLiteQuery -Path $path -Query "SELECT * FROM $TableName" # прочитать содержимое таблицы (в формате объекта)
```
`Get-Service | select Name,DisplayName,Status | ConvertTo-MySQLiteDB -Path $path -TableName Service -force` конвертировать объект в таблицу
### Database password
```PowerShell
$Connection = New-SQLiteConnection -DataSource $path
$Connection.ChangePassword("password")
$Connection.Close()
Invoke-SqliteQuery -Query "SELECT * FROM Service" -DataSource "$path;Password=password"
```
# MySQL
`apt -y install mysql-server mysql-client` \
`mysql -V` \
`systemctl status mysql` \
`mysqladmin -u root password` задать пароль root
`nano /etc/mysql/mysql.conf.d/mysqld.cnf`
```
[mysqld]
user = mysql
# pid-file = /var/run/mysqld/mysqld.pid
# socket = /var/run/mysqld/mysqld.sock
# port = 3306
# datadir = /var/lib/mysql
# tmpdir = /tmp
bind-address = 0.0.0.0
mysqlx-bind-address = 0.0.0.0
log_error = /var/log/mysql/error.log
```
`systemctl restart mysql` \
`ss -tulnp | grep 3306` \
`ufw allow 3306/tcp` \
`nc -zv 192.168.1.253 3306` \
`tnc 192.168.1.253 -p 3306`
`mysql -u root -p` \
`SELECT user(), now(), version();` \
`quit;`
`mysql -u root -p -e 'SHOW TABLES FROM db_aduser;'` отобразить список таблиц без подключения к консоли MySQL
`CREATE` создать БД, пользователя, таблицу \
`ALTER` управление столбцами таблице \
`DROP` удалить БД, пользователя, таблицу \
`USE` выбрать БД \
`SHOW` вывесли список БД, прав доступа пользователя (GRANTS), названия столбцов и их свойства \
`GRANT` дать доступ пользователю к БД \
`REVOKE` удалить доступ пользователя к БД \
`UPDATE` изменить права доступа, значения с таблице \
`FLUSH` обновить права доступа \
`SELECT` отобразить выбранную БД, вывести список пользователей, выборка данных в таблице \
`INSERT` внести данные \
`DELETE` удалить данные в (FROM) таблице
### DATA TYPE
`VARCHAR(N)` строка переменной длины, в формате ASCII, где один символ занимает 1 байт, числом N указывается максимальная возможная длина строки \
`NVARCHAR(N)` строка переменной длины, в формате Unicode, где один символ занимает 2 байта \
`CHAR(N)/nchar(N)` строка фиксированной длины, которая всегда дополняется справа пробелами до длины N и в базе данных она занимает ровно N символов \
`INT` целое число, от -2147483648 до 2147483647, занимает 4 байта \
`FLOAT` число, в котором может присутствовать десятичная точка (запятая) \
`BIT` флаг, Да - 1 или Нет - 0 \
`DATE` формат даты, например 25.05.2023 \
`TIME` 23:30:55.1234567 \
`DATETIME` 25.05.2023 23:30:55.1234567
### DATABASE
```
SHOW databases; # вывести список БД
CREATE DATABASE db_aduser; # создать БД
CREATE DATABASE db_rep DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; # создать БД с кодировкой UTF-8
DROP DATABASE db_rep; # удалить БД
USE db_aduser; # выбрать/переключиться на выбранную БД
SELECT database(); # отобразить выбранную БД
```
### USER
```
SELECT USER,HOST FROM mysql.user; # вывести список УЗ
CREATE USER posh@localhost IDENTIFIED BY '1qaz!QAZ'; # создать УЗ, которая будет подключаться с локального сервера
CREATE USER posh@localhost IDENTIFIED BY '1qaz!QAZ'; # создать УЗ, которая будет подключаться с указанного сервера
CREATE USER posh@'192.168.3.99' IDENTIFIED BY '1qaz!QAZ'; # УЗ для доступа с конкретного сервера
CREATE USER 'admin'@'%' IDENTIFIED BY 'Admin12#'; # УЗ для доступа с любого сервера (% - wildcard)
DROP USER posh@localhost; # удалить пользователя
SHOW GRANTS FOR posh@'%'; # отобразить права доступа пользователя
GRANT ALL PRIVILEGES ON db_aduser.* TO posh@'192.168.3.99'; # полный доступ для posh к БД db_aduser
GRANT ALL PRIVILEGES ON *.* TO posh@'%'; # доступ к всем БД c любого клиентского хоста
GRANT SELECT,DELETE ON mysql.* TO posh@'%'; # права SELECT и DELETE на встроенную БД mysql
REVOKE DELETE ON mysql.* FROM posh@'%'; # удалить доступ DELETE
UPDATE mysql.user SET super_priv='Y' WHERE USER='posh' AND host='%'; # изменить привелегии для пользователя
SELECT USER,HOST,super_priv FROM mysql.user; # список УЗ и таблица с правами SUPER privilege
FLUSH PRIVILEGES; # обновить права доступа
```
### TABLE
```
SHOW TABLES; # отобразить список всех таблиц
SHOW TABLES LIKE '%user'; # поиск таблицы по wildcard-имени
CREATE TABLE table_aduser (id INT NOT NULL AUTO_INCREMENT, Name VARCHAR(100), email VARCHAR(100), PRIMARY KEY (ID)); # создать таблицу
DROP TABLE table_aduser; # удалить таблицу
```
### COLUMN
```
SHOW COLUMNS FROM table_aduser; # отобразить название стобцов и их свойства
ALTER TABLE table_aduser DROP COLUMN id; # удалить столбец id
ALTER TABLE table_aduser ADD COLUMN info VARCHAR(10); # добавить столбец info
ALTER TABLE table_aduser CHANGE info new_info VARCHAR(100); # изменить имя столбца info на new_info и его тип данных
ALTER TABLE table_aduser ADD COLUMN (id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (ID)); # добавить столбец id
```
### INSERT
```
INSERT table_aduser (Name,email) VALUES ('Alex','no-email');
INSERT table_aduser (Name,email) VALUES ('Alex','no-email');
INSERT table_aduser (Name) VALUES ('Support');
INSERT table_aduser (Name) VALUES ('Jack');
```
### SELECT
```
SELECT * FROM table_aduser; # содержимое всех стобцов в выбранной (FROM) таблице
SELECT Name,email FROM table_aduser; # содержимое указанных стобцов
SELECT DISTINCT Name,Email FROM table_aduser; # отобразить уникальные записи (без повторений)
SELECT * FROM table_aduser ORDER BY Name; # отсортировать по Name
SELECT * FROM table_aduser ORDER BY Name DESC; # обратная сортировка
SELECT COUNT(*) FROM table_aduser; # количество строк в таблице
SELECT COUNT(new_info) FROM table_aduser; # количество строк в столбце
```
### WHERE
```
NOT; AND; OR # по приоритетам условий
SELECT * FROM table_aduser WHERE Name = 'Alex'; # поиск по содержимому
SELECT * FROM table_aduser WHERE NOT Name != 'Alex'; # условие NOT где Name не равен значению
SELECT * FROM table_aduser WHERE email != ''; # вывести строки, где содержимое email не рано null
SELECT * FROM table_aduser WHERE email != '' OR id > 1000; # или id выше 1000
SELECT * FROM table_aduser WHERE Name RLIKE "support"; # регистронезависемый (RLIKE) поиск
SELECT * FROM table_aduser WHERE Name RLIKE "^support"; # начинаются только с этого словосочетания
```
### DELETE
```
SELECT * FROM table_aduser WHERE Name RLIKE "alex"; # найти и проверить значения перед удалением
DELETE FROM table_aduser WHERE Name RLIKE "alex"; # Query OK, 2 rows affected # удалено две строки
DELETE FROM table_aduser; # удалить ВСЕ значения
```
### UPDATE
```
SELECT * FROM table_aduser WHERE Name = 'Jack'; # найти и проверить значение перед изменением
UPDATE table_aduser SET Name = 'Alex' WHERE Name = 'Jack'; # изменить значение 'Jack' на 'Alex'
UPDATE db_aduser.table_aduser SET Name='BCA' WHERE id=1; # изменить значение в строке с ID 1
```
### CHECK
```
CHECK TABLE db_aduser.table_aduser; # проверить
ANALYZE TABLE db_aduser.table_aduser; # анализировать
OPTIMIZE TABLE db_aduser.table_aduser; # оптимизировать
REPAIR TABLE db_aduser.table_aduser; # восстановить
TRUNCATE TABLE db_aduser.table_aduser; # очистить
```
### DUMP
```
mysqldump -u root -p --databases db_aduser > /bak/db_aduser.sql
mysql -u root -p db_aduser < /bak/db_aduser.sql
crontab -e
00 22 * * * /usr/bin/mysqldump -uroot -p1qaz!QAZ db_zabbix | /bin/bzip2 > `date +/dump/zabbix/zabbix-\%d-\%m-\%Y-\%H:\%M.bz2`
00 23 * * * /usr/bin/mysqldump -uroot -p1qaz!QAZ db_zabbix > `date +/dump/smb/zabbix-\%d-\%m-\%Y-\%H:\%M.sql`
0 0 * * * find /dump/zabbix -mtime +7 -exec rm {} \;
mysqldump -u root --single-transaction db_zabbix > /dump/zabbix/db_zabbix.sql
mysql -u user_zabbix -p -e 'CREATE DATABASE db_zabbix;'
mysql -u user_zabbix -p db_zabbix < /root/db_zabbix.sql
```
### innodb_force_recovery
```
sed -i '/innodb_force_recovery/d' /etc/mysql/my.cnf # удалить
mode=6; sed -i "/^\[mysqld\]/{N;s/$/\ninnodb_force_recovery=$mode/}" /etc/mysql/my.cnf # добавить mode 6
systemctl restart mysql
[mysqld]
innodb_force_recovery=1 # сервер пытается начать работу независимо от того, есть ли поврежденные данные InnoDB или нет
innodb_force_recovery=2 # удается восстановить работу за счет остановки потока команд, которые были частично выполнены или не выполнены (не запускает фоновые операции)
innodb_force_recovery=3 # отменяет откат после восстановления поврежденных файлов (не пытается откатить транзакции)
innodb_force_recovery=6 # запуск СУБД в режиме read only
```
### MySQL Connector NET
### Add-ADUser
```PowerShell
$ip = "192.168.1.253"
$user = "posh"
$pass = "1qaz!QAZ"
$db = "db_aduser"
Add-Type –Path "$home\Documents\MySQL-Connector-NET\8.0.31-4.8\MySql.Data.dll"
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{
ConnectionString="server=$ip;uid=$user;pwd=$pass;database=$db"
}
$Connection.Open()
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand
$Command.Connection = $Connection
$UserList = Get-ADUser -filter * -properties name,EmailAddress
foreach ($user in $UserList) {
$uname=$user.Name
$uemail=$user.EmailAddress
$Command.CommandText = "INSERT INTO table_aduser (Name,Email) VALUES ('$uname','$uemail')"
$Command.ExecuteNonQuery()
}
$Connection.Close()
```
### Get-ADUser
```PowerShell
$ip = "192.168.1.253"
$user = "posh"
$pass = "1qaz!QAZ"
$db = "db_aduser"
Add-Type –Path "$home\Documents\MySQL-Connector-NET\8.0.31-4.8\MySql.Data.dll"
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{
ConnectionString = "server=$ip;uid=$user;pwd=$pass;database=$db"
}
$Connection.Open()
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand
$Command.Connection = $Connection
$MYSQLDataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter
$MYSQLDataSet = New-Object System.Data.DataSet
$Command.CommandText = "SELECT * FROM table_aduser"
$MYSQLDataAdapter.SelectCommand = $Command
$NumberOfDataSets = $MYSQLDataAdapter.Fill($MYSQLDataSet, "data")
$Collections = New-Object System.Collections.Generic.List[System.Object]
foreach($DataSet in $MYSQLDataSet.tables[0]) {
$Collections.Add([PSCustomObject]@{
Name = $DataSet.name;
Mail = $DataSet.email
})
}
$Connection.Close()
$Collections
```
# MSSQL
`wget -qO- https://packages.microsoft.com/keys/microsoft.asc | apt-key add -` импортировать GPG-ключ для репозитория \
`https://packages.microsoft.com/config/ubuntu/` выбрать репозиторий и скопировать URL \
`add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list)"` \
`apt-get update` обновить список пакетов \
`apt-get install mssql-server` \
`/opt/mssql/bin/mssql-conf setup` скрипт начальной конфигурации (выбрать редакцию, 3 - express и русский язык 9 из 11) \
`systemctl status mssql-server` \
`curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -` установить клиент \
`curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list` \
`apt-get update` \
`apt-get install mssql-tools` \
`echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc` добавить в домашний каталог файла bashrc, что бы не писать путь к исполняемому файлу \
`export PATH="$PATH:/opt/mssql-tools/bin"` \
`iptables -I INPUT 1 -p tcp --dport 1433 -j ACCEPT`
```
sqlcmd -S localhost -U SA
CREATE DATABASE itinvent
go
SELECT name FROM master.dbo.sysdatabases
go
```
### System.Data.SqlClient
```PowerShell
$user = "itinvent"
$pass = "itinvent"
$db = "itinvent"
$srv = "192.168.3.103"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "server=$srv;database=$db;user id=$user;password=$pass;Integrated Security=false"
$SqlCommand = New-Object System.Data.SqlClient.SqlCommand` класс формата команды
$SqlCommand.CommandText = "SELECT * FROM ITINVENT.dbo.USERS"` отобразить содержимое таблицы
#$SqlCommand.CommandText = "SELECT LICENCE_DATE,DESCR,MODEL_NO,TYPE_NO FROM ITINVENT.dbo.ITEMS where LICENCE_DATE IS NOT NULL"
$SqlCommand.Connection = $SqlConnection` передать формат подключения
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter` создать адаптер подключения для выполнения SELECT запросов к БД
$SqlAdapter.SelectCommand = $SqlCommand` передать команду
$DataSet = New-Object System.Data.DataSet` создать объект приема данных формата XML
$SqlAdapter.Fill($DataSet)` заполнить данными полученные от адаптера (возвращает кол-во объектов)
$SqlConnection.Close()
$Data = $DataSet.Tables
$Data[0] | ft
```
### SqlClient INSERT
```PowerShell
$user = "itinvent"
$pass = "itinvent"
$db = "db_test"
$srv = "192.168.3.103"
$sql = "INSERT INTO table_test (column_user) VALUES ('lifailon')"` добавить данные в таблицу table_test в колонку column_user
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "server=$srv;database=$db;user id=$user;password=$pass;Integrated Security=false"
$SqlCommand = New-Object System.Data.SqlClient.SqlCommand
$SqlCommand.CommandText = $sql
$SqlCommand.Connection = $SqlConnection
$SqlConnection.Open()
$rowsAffected = $SqlCommand.ExecuteNonQuery();` для запросов INSERT/UPDATE/DELETE не используется SqlDataAdapter
$SqlConnection.Close()
```
### SSMS INSERT
```
USE [db_test]
GO
INSERT INTO [dbo].[table_test]
([column_user])
VALUES
('lifailon')
GO
SELECT TOP (1000) [column_user]
FROM [db_test].[dbo].[table_test]
```
### T-SQL
- DDL (Data Definition Language / Язык определения данных). К этому типу относятся команды, которые создают базу данных, таблицы, индексы, хранимые процедуры. \
`CREATE` создает объекты базы данных (саму базу даных, таблицы, индексы и т.д.) \
`ALTER` изменяет объекты базы данных \
`DROP` удаляет объекты базы данных \
`TRUNCATE` удаляет все данные из таблиц
- DML (Data Manipulation Language / Язык манипуляции данными). К этому типу относят команды по выбору, обновлению, добавлению и удалению данных. \
`SELECT` извлекает данные из БД \
`UPDATE` обновляет данные \
`INSERT` добавляет новые данные \
`DELETE` удаляет данные
- DCL (Data Control Language / Язык управления доступа к данным). К этому типу относят команды, которые управляют правами по доступу к данным. \
`GRANT` предоставляет права для доступа к данным \
`REVOKE` отзывает права на доступ к данным
```
-- Переменные
DECLARE @text NVARCHAR(20), @int INT;
SET @text='Test';
SET @int = 21;
select @text,@int
-- Имена сервера и экземпляра
Select @@SERVERNAME as [Server\Instance];
-- версия SQL Server
Select @@VERSION as SQLServerVersion;
-- Текущая БД (БД, в контексте которой выполняется запрос)
Select DB_NAME() AS CurrentDB_Name;
-- Время работы с момента запуска сервера
SELECT @@Servername AS ServerName ,
create_date AS ServerStarted ,
DATEDIFF(s, create_date, GETDATE()) / 86400.0 AS DaysRunning ,
DATEDIFF(s, create_date, GETDATE()) AS SecondsRunnig
FROM sys.databases
WHERE name = 'tempdb';
-- Количество активных соединений
SELECT @@Servername AS Server ,
DB_NAME(database_id) AS DatabaseName ,
COUNT(database_id) AS Connections ,
Login_name AS LoginName ,
MIN(Login_Time) AS Login_Time ,
MIN(COALESCE(last_request_end_time, last_request_start_time))
AS Last_Batch
FROM sys.dm_exec_sessions
WHERE database_id > 0
AND DB_NAME(database_id) NOT IN ( 'master', 'msdb' )
GROUP BY database_id ,
login_name
ORDER BY DatabaseName;
-- Статус Backup
SELECT @@Servername AS ServerName ,
d.Name AS DBName ,
MAX(b.backup_finish_date) AS LastBackupCompleted
FROM sys.databases d
LEFT OUTER JOIN msdb..backupset b
ON b.database_name = d.name
AND b.[type] = 'D'
GROUP BY d.Name
ORDER BY d.Name;
-- Путь к Backup
SELECT @@Servername AS ServerName ,
d.Name AS DBName ,
b.Backup_finish_date ,
bmf.Physical_Device_name
FROM sys.databases d
INNER JOIN msdb..backupset b ON b.database_name = d.name
AND b.[type] = 'D'
INNER JOIN msdb.dbo.backupmediafamily bmf ON b.media_set_id = bmf.media_set_id
ORDER BY d.NAME ,
b.Backup_finish_date DESC;
-- Вывести список всех БД, модели восстановления и путь к mdf/ldf
EXEC sp_helpdb;
SELECT @@SERVERNAME AS Server ,
d.name AS DBName ,
create_date ,
recovery_model_Desc AS RecoveryModel ,
m.physical_name AS FileName
FROM sys.databases d
JOIN sys.master_files m ON d.database_id = m.database_id
ORDER BY d.name;
-- Размер БД
with fs
as
(
select database_id, type, size * 8.0 / 1024 size
from sys.master_files
)
select
name,
(select sum(size) from fs where type = 0 and fs.database_id = db.database_id) DataFileSizeMB,
(select sum(size) from fs where type = 1 and fs.database_id = db.database_id) LogFileSizeMB
from sys.databases
-- Поиск таблицы по маске имени (вывод: названия схемы где распологается объект, тип объекта, дата создания и последней модификации):
select [object_id], [schema_id],
schema_name([schema_id]) as [schema_name],
[name],
[type],
[type_desc],
[create_date],
[modify_date]
from sys.all_objects
-- where [name]='INVENT';
where [name] like '%INVENT%';
-- Кол-во строк в таблицах
SELECT @@ServerName AS Server ,
DB_NAME() AS DBName ,
OBJECT_SCHEMA_NAME(p.object_id) AS SchemaName ,
OBJECT_NAME(p.object_id) AS TableName ,
i.Type_Desc ,
i.Name AS IndexUsedForCounts ,
SUM(p.Rows) AS Rows
FROM sys.partitions p
JOIN sys.indexes i ON i.object_id = p.object_id
AND i.index_id = p.index_id
WHERE i.type_desc IN ( 'CLUSTERED', 'HEAP' )
-- This is key (1 index per table)
AND OBJECT_SCHEMA_NAME(p.object_id) <> 'sys'
GROUP BY p.object_id ,
i.type_desc ,
i.Name
ORDER BY SchemaName ,
TableName;
-- Найти строковое (nvarchar) значение 2023 по всем таблицам базы данных
-- Отображается в какой таблице и столбце хранится значение, а также количество найденных пары таблица-колонка
set nocount on
declare @name varchar(128), @substr nvarchar(4000), @column varchar(128)
set @substr = '%2023%'
declare @sql nvarchar(max);
create table`rslt
(table_name varchar(128), field_name varchar(128), [value] nvarchar(max))
declare s cursor for select table_name as table_name from information_schema.tables where table_type = 'BASE TABLE' order by table_name
open s
fetch next from s into @name
while @@fetch_status = 0
begin
declare c cursor for
select quotename(column_name) as column_name from information_schema.columns
where data_type in ('text', 'ntext', 'varchar', 'char', 'nvarchar', 'char', 'sysname', 'int', 'tinyint') and table_name = @name
set @name = quotename(@name)
open c
fetch next from c into @column
while @@fetch_status = 0
begin
--print 'Processing table - ' + @name + ', column - ' + @column
set @sql='insert into`rslt select ''' + @name + ''' as Table_name, ''' + @column + ''', cast(' + @column +
' as nvarchar(max)) from' + @name + ' where cast(' + @column + ' as nvarchar(max)) like ''' + @substr + '''';
print @sql;
exec(@sql);
fetch next from c into @column;
end
close c
deallocate c
fetch next from s into @name
end
select table_name as [Table Name], field_name as [Field Name], count(*) as [Found Mathes] from`rslt
group by table_name, field_name
order by table_name, field_name
drop table`rslt
close s
deallocate s
-- Поиск в таблице [CI_HISTORY] и столбцу [HIST_ID]:
SELECT * FROM ITINVENT.dbo.CI_HISTORY where [HIST_ID] like '%2023%';
-- Узнать фрагментацию индексов
DECLARE @db_id SMALLINT;
SET @db_id = DB_ID(N'itinvent');
IF @db_id IS NULL
BEGIN;
PRINT N'Неправильное имя базы';
END;
ELSE
BEGIN;
SELECT
object_id AS [ID объекта],
index_id AS [ID индекса],
index_type_desc AS [Тип индекса],
avg_fragmentation_in_percent AS [Фрагментация в %]
FROM sys.dm_db_index_physical_stats(@db_id, NULL, NULL, NULL , 'LIMITED')
ORDER BY [avg_fragmentation_in_percent] DESC;
END;
GO
-- TempDB
-- Initial size - начальный/минимальный размер БД (1024 MB)
-- Autogrowh - прирост (512MB)
-- По умолчанию tempdb настроена на авто-расширение (Autogrow) и при каждой перезагрузке SQL Server пересоздаёт файлы этой БД с минимальным размером инициализации.
-- Увеличив размер инициализации файлов tempdb, можно свести к минимуму затраты системных ресурсов на операции авто-расширения.
-- Изменить путь к БД:
USE master;
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = tempdev, FILENAME = 'F:\tempdb.mdf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp2, FILENAME = 'F:\tempdb_mssql_2.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp3, FILENAME = 'F:\tempdb_mssql_3.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp4, FILENAME = 'F:\tempdb_mssql_4.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp5, FILENAME = 'F:\tempdb_mssql_5.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp6, FILENAME = 'F:\tempdb_mssql_6.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp7, FILENAME = 'F:\tempdb_mssql_7.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = temp8, FILENAME = 'F:\tempdb_mssql_8.ndf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = templog, FILENAME = 'F:\templog.ldf');
GO
-- Указать размер файла:
MODIFY FILE (NAME = temp2, FILENAME = 'F:\tempdb_mssql_2.ndf' , SIZE = 1048576KB , FILEGROWTH = 524288KB);
```
### Тип резервной копии
- Full (Полная копия). Когда стартует полное резервирование, записывается Log Sequence Number (LSN - последовательный номер журнала), а так же LSN записывается и при завершении полного резервирования. Этот LSN является механизмом, используемым SQL Server, чтобы знать, в каком порядке выполнялись операторы INSERT, UPDATE или DELETE. При этом наличие записанных LSN начала и окончания, как части полного бэкапа, обеспечивает согласованное с точки зрения транзакций резервное копирование, поскольку при полном резервном копировании учитываются изменения, произошедшие во время резервного копирования. Это обеспечивает обработку таких транзакций в процессе восстановления бэкапа.
- Differential (дифференциальная/разностная копия). Хранит данных, изменившиеся с момента последней Полной резервной копии. При восстановлении нужно сначала восстановить Полную резервную копию в режиме NORECOVERY, потом можно применить любую из последующих Разностных копий, без предыдущей Полной резервной копии Разностная копия бесполезна. Каждая последующая Разностная копия будет хранить все данные, входящие в предыдущую Разностную резервную копию, сделанную после предыдущей Полной копии.
- Incremental (инкрементальная/копия журналов транзакций). Резервное копирования журнала транзакций копирует все транзакции, которые произошли с момента последнего резервного копирования, а затем урезает журнал транзакций для освобождения дискового пространства. Транзакции происходят в определенном порядке (LSN), бэкап журнала поддерживает этот порядок транзакций. Бэкапы журналов транзакций должны восстанавливаться по порядку. Для восстановления базы данных потребуется вся цепочка резервных копий: полная и все последующие инкрементальные журнала транзакций.
### Модели восстановления
- Simple (Простая). Хранится только необходимый для жизни остаток журнала транзакций. Журнал транзакций (лог) автоматически очищается. Создание резервных копий журнала транзакций невозможна, поэтому остается самое ограниченное число опций по восстановлению. Недоступен функционал: Always On, Point-In-Time восстановление, Резервные копии журнала транзакций.
- Full (Полная). Хранится журнал транзакций всех изменений в БД с момента последнего резервного копирования журнала транзакций. Журнал транзакций не будет очищаться до тех пор, пока не будет сделана резервная копия журнала транзакций.
- Bulk logged (С неполным протоколированием). Идентична Full, за исключение: SELECT INTO, BULK INSERT и BCP, INSERT INTO SELECT, операции с индексами (CREATE INDEX, ALTER INDEX REBUILD, DROP INDEX)
### Системные БД
- master. Хранятся все данные системного уровня (конфигурация системы, сведенья об учетных записях входа, информация обо всех других базах данных) для экземпляра SQL Server.
- tempdb. Рабочее пространство для временных объектов, таких как глобальные или локальные временные таблицы, временные хранимые процедуры, табличные переменные и курсоры. Пересоздаётся при каждом запуске SQL Server.
- model. Используется в качестве шаблона для всех баз данных, создаваемых в экземпляре SQL Server, все содержимое базы данных model, включая параметры базы данных, копируется в создаваемую базу данных. Так как база данных tempdb создается каждый раз при запуске SQL Server, база данных model всегда должна существовать в системе SQL Server.
- msdb. Используется агентом SQL Server для создания расписания предупреждений (оператор) и выполнение заданий, а также другими компонентами. SQL Server хранит полный журнал резервного копирования и восстановления в базе данных msdb. Для отправки почты оператору используется: USE [msdb].
- resource. Доступная только для чтения база данных, которая содержит все системные объекты, например sys.objects, физически хранятся в базе данных resource, но логически присутствуют в схеме sys каждой базы данных.
### Регламентные операции
- Проверка целостности базы данных
`DBCC CHECKDB`
- Индексы. Индексы используются для быстрого поиска данных без необходимости поиска/просмотра всех строк в таблице базы данных при каждом обращении к таблице базы данных. Индекс ускоряет процесс запроса, предоставляя быстрый доступ к строкам данных в таблице, аналогично тому, как указатель в книге помогает вам быстро найти необходимую информацию. Индексы предоставляют путь для быстрого поиска данных на основе значений в этих столбцах. Для каждого индекса обязательно хранится его статистика. MS SQL Server самостоятельно создает и изменяет индексы при работе с базой. С течением времени данные в индексе становятся фрагментированными, т.е. разбросанными по базе данных, что серьезно снижает производительность запросов. Если фрагментация составляет от 5 до 30% (стандартно в задании 15%), то рекомендуется ее устранить с помощью реорганизации, при фрагментации выше 30% (по умолчанию в задаче > 30% фрагментации и число страниц > 1000) необходимо полное перестроение индексов. После перестроения планово используется только реорганизация.
- Реорганизация (Reorganize) или дефрагментация индекса — это серия небольших локальных перемещений страниц так, чтобы индекс не был фрагментирован. После реорганизации статистика не обновляется. Во время выполнения почти все данные доступны, пользователи смогут работать.
`sp_msforeachtable N'DBCC INDEXDEFRAG (<имя базы данных>, ''?'')'`
- Перестроение (Rebuild) индексов (или задача в мастере планов обслуживания: Восстановить индекс) запускает процесс полного построения индексов. В версии MS SQL Server Standard происходит отключение всех клиентов от базы на время выполнения операции. После перестроения обязательно обновляется статистика.
`sp_msforeachtable N'DBCC DBREINDEX (''?'')'`
- Обновление статистики. Статистика — небольшая таблица (обычно до 200 строк), в которой хранится обобщенная информация о том, какие значения и как часто встречаются в таблице. На основании статистики сервер принимает решение, как лучше построить запрос. Когда происходят запросы к БД (например, SELECT) вы получаете данные, но не описываете то, как эти данные должны быть извлечены. В получении и обработке данных помогает статистика. Во время выполнения процедуры обновления статистики данные не блокируются.
`exec sp_msforeachtable N'UPDATE STATISTICS ? WITH FULLSCAN'`
- Очистка процедурного кэша, выполняется после обновления статистики. Оптимизатор MS SQL Server кэширует планы запросов для их повторного выполнения. Это делается для того, чтобы экономить время, затрачиваемое на компиляцию запроса в том случае, если такой же запрос уже выполнялся и его план известен. После обновия статистики, не будет очищен процедурный кэш, то SQL Server может выбрать старый (неоптимальный) план запроса из кэша вместо того, чтобы построить новый (более оптимальный) план.
`DBCC FREEPROCCACHE`
# InfluxDB
https://community.influxdata.com/t/influxdb-1-7-11-download-links/18898` InfluxDB1 \
`wget https://dl.influxdata.com/influxdb/releases/influxdb2-2.7.1-windows-amd64.zip -UseBasicParsing -OutFile influxdb2-2.7.1-windows-amd64.zip` скачать InfluxDB2 \
`Expand-Archive .\influxdb2-2.7.1-windows-amd64.zip -DestinationPath 'C:\Program Files\InfluxData\influxdb\'` разархивировать \
`cd "C:\Program Files\InfluxData\influxdb\influxdb2_windows_amd64"` \
`.\influxd.exe` \
`.\influxd -h` \
`http://localhost:8086/` базовая настройка \
API Token: `wqsqOIR3d-PYmiJQYir4sX_NjtKKyh8ZWbfX1ZlfEEpAH3Z2ylcHx3XZzUA36XO3HIosiCFkhi4EoWfHxwIlAA==`
### CLI Client
`wget https://dl.influxdata.com/influxdb/releases/influxdb2-client-2.7.3-windows-amd64.zip?_gl=1*76m6hu*_ga*MTg0OTc4MzkzNC4xNjg4MTM5NzQ4*_ga_CNWQ54SDD8*MTY4ODE2MjA0My41LjEuMTY4ODE2MzI5Ni4yMi4wLjA. -UseBasicParsing -OutFile influxdb2-client-2.7.3-windows-amd64.zip` \
`Expand-Archive .\influxdb2-client-2.7.3-windows-amd64.zip -DestinationPath 'C:\Program Files\InfluxData\influx'` \
`cd "C:\Program Files\InfluxData\influx"`
`.\influx org list` отобразить список пользователей организаций \
`.\influx auth list` отобразить список пользователей и токенов \
`.\influx v1 shell` консоль \
`.\influx v1 dbrp list` список БД
```
.\influx config create --config-name main `
--host-url "http://localhost:8086" `
--org "test" `
--token "wqsqOIR3d-PYmiJQYir4sX_NjtKKyh8ZWbfX1ZlfEEpAH3Z2ylcHx3XZzUA36XO3HIosiCFkhi4EoWfHxwIlAA==" `
--active` создать и активировать конфигурацию, что бы не передавать свой хост InfluxDB, токен API и организацию с каждой командой
```
`.\influx config list` список конфигураций \
`.\influx config list --json | ConvertFrom-Json` отобразить конфигурацию с выводом токена \
`.\influx server-config | ConvertFrom-Json` текущая конфигурация сервера
### bucket
`.\influx bucket create --name test-bucket -c main` создать корзину \
`.\influx write --bucket test-bucket --url https://influx-testdata.s3.amazonaws.com/air-sensor-data-annotated.csv` записать данные из CSV в созданную корзину (Flux language) \
`.\influx query 'from(bucket:\"test-bucket\") |> range(start:-30m) |> mean()'` получить записанные данные
### user
`.\influx user create -n root -o test` создать пользователя (-o ) \
`.\influx user password -n admin -p "password"` изменить/задать пароль \
`.\influx user list` список пользователей \
`influx user delete -i `
### deb
`wget https://repos.influxdata.com/debian/packages/influxdb2-2.7.1-amd64.deb` \
`dpkg -i influxdb2-2.7.1-amd64.deb` \
`systemctl start influxd.service` \
`systemctl status influxd.service` \
`netstat -natpl | grep 80[8-9][3-9]` \
`ps aux | grep influxdb | grep -Ev "grep"`
`nano /etc/influxdb/config.toml` v2 \
`http-bind-address = "192.168.3.101:8086"`
`nano /etc/influxdb/influxdb.conf` v1
```
[http]
enabled = true` включить API
bind-address = "192.168.3.104:8086"
auth-enabled = true` включить авторизацию
```
`apt install influxdb-client` \
`influx` \
`influx --host 192.168.3.104 --username admin --password password`
### USERS
`SHOW USERS` отобразить пользователей и их права доступа \
`CREATE USER admin WITH PASSWORD 'password' WITH ALL PRIVILEGES` создать пользователя \
`GRANT ALL PRIVILEGES TO "admin"` предоставить права доступа \
`GRANT READ ON "database" TO "admin"` доступ на чтение для БД или запись (WRITE) \
`REVOKE ALL PRIVILEGES FROM "admin"` отозвать права доступа \
`SHOW GRANTS FOR "admin"` БД и привелегии доступа для указанного пользователя \
`SET PASSWORD FOR "admin" = 'new_password'` изменить пароль \
`DROP USER "admin"` удалить пользователя
### DATABASE
`CREATE DATABASE powershell` создать БД \
`SHOW DATABASES` отобразить список БД \
`DROP DATABASE powershell` удалить БД \
`USE powershell` \
`SHOW measurements` отобразить все таблицы \
`INSERT performance,host=console,counter=CPU value=0.88` записать данные в таблицу performance
### SELECT/WHERE
`SELECT * FROM performance` отобразить все данные в таблице \
`SELECT value FROM performance` отфильтровать по столбцу value (только Field Keys) \
`SELECT * FROM performance limit 10` отобразить 10 единиц данных \
`SELECT * FROM performance WHERE time > now() -2d` отобразить данные за последние 2 дня \
`SELECT * FROM performance WHERE time > now() +3h -5m` данные за последние 5 минут (+3 часа от текущего времени по UTC 0 -5 минут) \
`SELECT * FROM performance WHERE counter = 'CPU'` выборка по тэгу \
`SELECT upload/1000 FROM speedtest WHERE upload/1000 <= 250` выборка по столбцу upload и разделить вывод на 1000, вывести upload меньше 250 \
`DELETE FROM performance WHERE time > now() -1h` удалить данные за последние 1/4 часа \
`DELETE FROM performance WHERE time < now() -24h` удалить данные старше 24 часов
### REGEX
`SELECT * FROM "performance" WHERE host =~ /.*-Pro/` приблизительно равно любое значение и на конце -Pro \
`SELECT * FROM "win_pdisk" WHERE instance =~/.*C:/ and time > now() - 5m` и \
`SELECT * FROM "win_pdisk" WHERE instance =~/.*E:/ or instance =~ /.*F:/` или \
`SELECT * FROM "win_pdisk" WHERE instance !~ /.*Total/` не равно (исключить) \
### GROUP BY tag_key
`SELECT * FROM "win_pdisk" WHERE instance !~ /.*Total/ and instance !~/.*C:/ GROUP BY instance` группировать результаты по тегу
### Functions(field_key)
https://docs.influxdata.com/influxdb/v1.8/query_language/functions/ \
`SELECT instance,LAST(Avg._Disk_Read_Queue_Length) FROM "win_pdisk" GROUP BY instance` отфильтровать вывод по последнему/текущему значению \
`SELECT instance,FIRST(Avg._Disk_Read_Queue_Length) FROM "win_pdisk" GROUP BY instance` отфильтровать вывод по первому значению за весь или указанный отрезок времени \
`SELECT instance,MIN(Avg._Disk_Read_Queue_Length) FROM "win_pdisk" GROUP BY instance` отфильтровать вывод с отображением минимального значения \
`SELECT instance,MAX(Avg._Disk_Read_Queue_Length) FROM "win_pdisk" GROUP BY instance` отфильтровать вывод с отображением максимального значения \
`SELECT SUM(Bytes_Received_persec) FROM "win_net" GROUP BY instance` суммах всех значений \
`SELECT COUNT(Bytes_Received_persec) FROM "win_net" WHERE Bytes_Received_persec >= 0 GROUP BY instance` кол-во данных, где значение выше или равно 0 \
`SELECT MEAN(Bytes_Received_persec) FROM "win_net" WHERE Bytes_Received_persec < 1000 GROUP BY instance` среднее значение данных с показателем от 0 до 1000 (509)
### POLICY
`CREATE DATABASE powershell WITH DURATION 48h REPLICATION 1 NAME "del2d"` создать БД с политикой хранения 2 дня \
`CREATE RETENTION POLICY del2h ON powershell DURATION 2h REPLICATION 1` создать новую политику хранения для БД \
`CREATE RETENTION POLICY del6h ON powershell DURATION 6h REPLICATION 1 SHARD DURATION 2h` указать период хранения 6 часов + 2 часа до очистки (по умолчанию 1ч или больше) \
`ALTER RETENTION POLICY del6h ON powershell DEFAULT` изменить (ALTER) политику хранения для БД на del6h (DEFAULT) \
`DROP RETENTION POLICY del2d ON powershell` удаление политики хранения приводит к безвозвратному удалению всех измерений (таблиц) и данных, хранящихся в политике хранения
### API POST
Вместо таблиц в InfluxDB имеются измерения. Вместо столбцов в ней есть теги и поля.
```
Table Tag (string/int) Field (double/int) TIMESTAMP
measurement,Tag_Keys1=Tag_Values1,Tag_Keys2=Tag_Values2 Field_Keys1="Values",Field_Keys2="Values" 0000000000000000000
1 2 3
$ip = "192.168.3.104"
$port = "8086"
$db = "powershell"
$table = "speedtest"
$ipp = $ip+":"+$port
$url = "http://$ipp/write?db=$db"
$user = "admin"
$pass = "password" | ConvertTo-SecureString -AsPlainText -Force
$cred = [System.Management.Automation.PSCredential]::new($user,$pass)
$unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds
$timestamp = ([string]$unixtime -replace "\..+") + "000000000"
Invoke-RestMethod -Method POST -Uri $url -Body "$table,host=$(hostname) download=200000,upload=300000,ping=3 $timestamp"
```
### API GET
`curl http://192.168.3.104:8086/query --data-urlencode "q=SHOW DATABASES"` pwsh7 (ConvertFrom-Json) and bash
`$dbs = irm "http://192.168.3.104:8086/query?q=SHOW DATABASES"` \
`$dbs = irm "http://192.168.3.104:8086/query?epoch=ms&u=admin&p=password&q=SHOW DATABASES"` \
`$dbs.results.series.values`
```PowerShell
$ip = "192.168.3.104"
$port = "8086"
$db = "powershell"
$table = "speedtest"
$query = "SELECT * FROM $table"
$ipp = $ip+":"+$port
$url = "http://$ipp/query?db=$db&q=$query"
$data = Invoke-RestMethod -Method GET -Uri $url` -Credential $cred
$data.results.series.name ` имя таблицы
$data.results.series.columns` столбцы/ключи
$data.results.series.values ` данные построчно
```
### Endpoints
https://docs.influxdata.com/influxdb/v1.7/tools/api/
```PowerShell
$stats = irm http://192.168.3.104:8086/debug/vars` статистика сервера
$stats."database:powershell".values` кол-во таблиц к БД
$stats.queryExecutor.values` количество query-запросов (обращений к endpoint /query)
$stats.write.values` количество write-запросов
$stats.system.uptime
```
`http://192.168.3.104:8086/debug/requests` кол-во клиентских HTTP-запросов к конечным точкам /writeи /query \
`http://192.168.3.104:8086/debug/pprof` \
`http://192.168.3.104:8086/ping` \
`http://192.168.3.104:8086/query` \
`http://192.168.3.104:8086/write`
`http://192.168.3.99:8086/api/v2/setup` \
`http://192.168.3.99:8086/api/v2/config` \
`http://192.168.3.99:8086/api/v2/write`
### PingTo-InfluxDB
```PowerShell
while ($true) {
$tz = (Get-TimeZone).BaseUtcOffset.TotalMinutes
$unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End ((Get-Date).AddMinutes(-$tz))).TotalSeconds` -3h UTC
$timestamp = ([string]$unixtime -replace "\..+") + "000000000"
$tnc = tnc 8.8.8.8
$Status = $tnc.PingSucceeded
$RTime = $tnc.PingReplyDetails.RoundtripTime
Invoke-RestMethod -Method POST -Uri "http://192.168.3.104:8086/write?db=powershell" -Body "ping,host=$(hostname) status=$status,rtime=$RTime $timestamp"
sleep 1
}
```
`SELECT * FROM ping WHERE status = false`
### PerformanceTo-InfluxDB
```PowerShell
function ConvertTo-Encoding ([string]$From, [string]$To) {
Begin {
$encFrom = [System.Text.Encoding]::GetEncoding($from)
$encTo = [System.Text.Encoding]::GetEncoding($to)
}
Process {
$bytes = $encTo.GetBytes($_)
$bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
$encTo.GetString($bytes)
}
}
$localization = (Get-Culture).LCID` текущая локализация
if ($localization -eq 1049) {
$performance = "\\$(hostname)\Процессор(_Total)\% загруженности процессора" | ConvertTo-Encoding UTF-8 windows-1251` декодировать кириллицу
} else {
$performance = "\Processor(_Total)\% Processor Time"
}
$tz = (Get-TimeZone).BaseUtcOffset.TotalMinutes
while ($true) {
$unixtime = (New-TimeSpan -Start (Get-Date "01/01/1970") -End ((Get-Date).AddMinutes(-$tz))).TotalSeconds` -3h UTC
$timestamp = ([string]$unixtime -replace "\..+") + "000000000"
[double]$value = (Get-Counter $performance).CounterSamples.CookedValue.ToString("0.00").replace(",",".")` округлить в тип данных Double
Invoke-RestMethod -Method POST -Uri "http://192.168.3.104:8086/write?db=powershell" -Body "performance,host=$(hostname),counter=CPU value=$value $timestamp"
sleep 5
}
```
### Service
```PowerShell
$powershell_Path = (Get-Command powershell).Source
$NSSM_Path = "C:\NSSM\NSSM-2.24.exe"
$Script_Path = "C:\NSSM\PerformanceTo-InfluxDB.ps1"
$Service_Name = "PerformanceTo-InfluxDB"
& $NSSM_Path install $Service_Name $powershell_Path -ExecutionPolicy Bypass -NoProfile -f $Script_Path
Get-Service $Service_Name | Start-Service
Get-Service $Service_Name | Set-Service -StartupType Automatic
```
# Telegraf
Plugins: https://docs.influxdata.com/telegraf/v1.27/plugins/#input-plugins
`iwr https://dl.influxdata.com/telegraf/releases/telegraf-1.27.1_windows_amd64.zip -UseBasicParsing -OutFile telegraf-1.27.1_windows_amd64.zip` \
`Expand-Archive .\telegraf-1.27.1_windows_amd64.zip -DestinationPath "C:\Telegraf"` \
`rm telegraf-1.27.1_windows_amd64.zip` \
`cd C:\Telegraf` \
`.\telegraf.exe -sample-config --input-filter cpu:mem:dns_query --output-filter influxdb > telegraf_nt.conf` создать конфигурацию с выбарнными плагинами для сбора метрик \
`Start-Process notepad++ C:\Telegraf\telegraf_nt.conf`
```
[[outputs.influxdb]]
urls = ["http://192.168.3.104:8086"]
database = "telegraf_nt"
username = "user"
password = "pass"
[[inputs.cpu]]
percpu = false
totalcpu = true
[[inputs.dns_query]]
servers = ["8.8.8.8"]
network = "udp"
domains = ["."]
record_type = "A"
port = 53
timeout = "2s"
```
`.\telegraf.exe --test -config C:\Telegraf\telegraf_nt.conf` тест конфигурации (получения метрик с выводом в консоль) \
`C:\Telegraf\telegraf.exe -config C:\Telegraf\telegraf_nt.conf` запустить telegraf (тест отправки данных) \
`.\telegraf.exe --config "C:\Telegraf\telegraf_nt.conf" --service install` создать службу \
`Get-Service telegraf | Start-Service` \
`.\telegraf.exe --service uninstall`
`USE telegraf` \
`SELECT usage_idle,usage_system,usage_user FROM cpu`
# Elasticsearch
`Install-Module -Name Elastic.Console -AllowPrerelease` https://github.com/elastic/powershell/blob/master/Elastic.Console/README.md \
`Get-Command -Module Elastic.Console` \
`Get-ElasticsearchVersion` \
`Set-ElasticsearchVersion 7.3.0` \
`Invoke-Elasticsearch` REST API запросы
# CData
https://www.powershellgallery.com/profiles/CData \
https://www.cdata.com/kb/tech/elasticsearch-ado-powershell.rst
`Install-Module ElasticsearchCmdlets` https://www.powershellgallery.com/packages/ElasticsearchCmdlets/23.0.8565.1 \
`Import-Module ElasticsearchCmdlets` \
`Get-Command -Module ElasticsearchCmdlets`
```PowerShell
$elasticsearch = Connect-Elasticsearch -Server "$Server" -Port "$Port" -User "$User" -Password "$Password"
$shipcity = "New York"
$orders = Select-Elasticsearch -Connection $elasticsearch -Table "Orders" -Where "ShipCity = `'$ShipCity`'"` поиск и получение данных
$orders = Invoke-Elasticsearch -Connection $elasticsearch -Query 'SELECT * FROM Orders WHERE ShipCity = @ShipCity' -Params @{'@ShipCity'='New York'}` SQL запросы
```
### ADO.NET Assembly
`Install-Package CData.Elasticsearch` https://www.nuget.org/packages/CData.Elasticsearch \
`[Reflection.Assembly]::LoadFile("C:\Program Files\PackageManagement\NuGet\Packages\CData.Elasticsearch.23.0.8565\lib\net40\System.Data.CData.Elasticsearch.dll")`
```PowerShell
$connect = New-Object System.Data.CData.Elasticsearch.ElasticsearchConnection("Server=127.0.0.1;Port=9200;User=admin;Password=123456;")
$connect.Open()
$sql = "SELECT OrderName, Freight from Orders"
$da = New-Object System.Data.CData.Elasticsearch.ElasticsearchDataAdapter($sql, $conn)
$dt = New-Object System.Data.DataTable
$da.Fill($dt)
$dt.Rows | foreach {
Write-Host $_.ordername $_.freight
}
```
### UPDATE
```PowerShell
Update-Elasticsearch -Connection $Elasticsearch -Columns @('OrderName','Freight') -Values @('MyOrderName', 'MyFreight') -Table Orders -Id "MyId"
$cmd = New-Object System.Data.CData.Elasticsearch.ElasticsearchCommand("UPDATE Orders SET ShipCity='New York' WHERE Id = @myId", $conn)
$cmd.Parameters.Add(new System.Data.CData.Elasticsearch.ElasticsearchParameter("@myId","10456255-0015501366"))
$cmd.ExecuteNonQuery()
```
### INSERT
```PowerShell
Add-Elasticsearch -Connection $Elasticsearch -Table Orders -Columns @("OrderName", "Freight") -Values @("MyOrderName", "MyFreight")
$cmd = New-Object System.Data.CData.Elasticsearch.ElasticsearchCommand("INSERT INTO Orders (ShipCity) VALUES (@myShipCity)", $conn)
$cmd.Parameters.Add(new System.Data.CData.Elasticsearch.ElasticsearchParameter("@myShipCity","New York"))
$cmd.ExecuteNonQuery()
```
### DELETE
```PowerShell
Remove-Elasticsearch -Connection $Elasticsearch -Table "Orders" -Id "MyId"
$cmd = New-Object System.Data.CData.Elasticsearch.ElasticsearchCommand("DELETE FROM Orders WHERE Id=@myId", $conn)
$cmd.Parameters.Add(new System.Data.CData.Elasticsearch.ElasticsearchParameter("@myId","001d000000YBRseAAH"))
$cmd.ExecuteNonQuery()
```
# ODBC
`Get-Command -Module Wdac` \
`Get-OdbcDriver | ft` список установленных драйверов
https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-client-apps-ps1.html
```PowerShell
$connectstring = "DSN=Local Elasticsearch;"
$sql = "SELECT * FROM library"
$conn = New-Object System.Data.Odbc.OdbcConnection($connectstring)
$conn.open()
$cmd = New-Object system.Data.Odbc.OdbcCommand($sql,$conn)
$da = New-Object system.Data.Odbc.OdbcDataAdapter($cmd)
$dt = New-Object system.Data.datatable
$null = $da.fill($dt)
$conn.close()
$dt
```
# PostgreSQL
Скачать и установить драйвер: https://www.postgresql.org/ftp/odbc/versions/msi/
```PowerShell
$dbServer = "192.168.3.101"
$port = "5432"
$dbName = "test"
$dbUser = "admin"
$dbPass = "admin"
$szConnect = "Driver={PostgreSQL Unicode(x64)};Server=$dbServer;Port=$port;Database=$dbName;Uid=$dbUser;Pwd=$dbPass;"
$cnDB = New-Object System.Data.Odbc.OdbcConnection($szConnect)
$dsDB = New-Object System.Data.DataSet
try {
$cnDB.Open()
$adDB = New-Object System.Data.Odbc.OdbcDataAdapter
$adDB.SelectCommand = New-Object System.Data.Odbc.OdbcCommand("SELECT id, name, age, login FROM public.users" , $cnDB)
$adDB.Fill($dsDB)
$cnDB.Close()
}
catch [System.Data.Odbc.OdbcException] {
$_.Exception
$_.Exception.Message
$_.Exception.ItemName
}
foreach ($row in $dsDB[0].Tables[0].Rows) {
$row.login
$row.age
}
```
# WMI
### WMI/CIM (Windows Management Instrumentation/Common Information Model)
`Get-WmiObjec -ComputerName localhost -Namespace root -class "__NAMESPACE" | select name,__namespace` отобразить дочернии Namespace (логические иерархические группы) \
`Get-WmiObject -List` отобразить все классы пространства имен "root\cimv2" (по умолчанию), свойства (описывают конфигурацию и текущее состояние управляемого ресурса) и их методы (какие действия позволяет выполнить над этим ресурсом) \
`Get-WmiObject -List | Where-Object {$_.name -match "video"}` поиск класса по имени, его свойств и методов \
`Get-WmiObject -ComputerName localhost -Class Win32_VideoController` отобразить содержимое свойств класса
`gwmi -List | where name -match "service" | ft -auto` если в таблице присутствуют Methods, то можно взаимодействовать {StartService, StopService} \
`gwmi -Class win32_service | select *` отобразить список всех служб и всех их свойств \
`Get-CimInstance Win32_service` обращается на прямую к "root\cimv2" \
`gwmi win32_service -Filter "name='Zabbix Agent'"` отфильтровать вывод по имени \
`(gwmi win32_service -Filter "name='Zabbix Agent'").State` отобразить конкретное свойство \
`gwmi win32_service -Filter "State = 'Running'"` отфильтровать запущенные службы \
`gwmi win32_service -Filter "StartMode = 'Auto'"` отфильтровать службы по методу запуска \
`gwmi -Query 'select * from win32_service where startmode="Auto"'` WQL-запрос (WMI Query Language) \
`gwmi win32_service | Get-Member -MemberType Method` отобразить все методы взаимодействия с описание применения (Delete, StartService) \
`(gwmi win32_service -Filter 'name="Zabbix Agent"').Delete()` удалить службу \
`(gwmi win32_service -Filter 'name="MSSQL$MSSQLE"').StartService()` запустить службу
`Get-CimInstance -ComputerName $srv Win32_OperatingSystem | select LastBootUpTime` время последнего включения \
`gwmi -ComputerName $srv -Class Win32_OperatingSystem | select LocalDateTime,LastBootUpTime` текущее время и время последнего включения \
`gwmi Win32_OperatingSystem | Get-Member -MemberType Method` методы reboot и shutdown \
`(gwmi Win32_OperatingSystem -EnableAllPrivileges).Reboot()` используется с ключем повышения привелегий \
`(gwmi Win32_OperatingSystem -EnableAllPrivileges).Win32Shutdown(0)` завершение сеанса пользователя
```PowerShell
$system = Get-WmiObject -Class Win32_OperatingSystem
$InstallDate = [Management.ManagementDateTimeconverter]::ToDateTime($system.installdate)` Получаем дату установки ОС
$AfterInstallDays = ((Get-Date) — $Installdate).Days` Вычисляем время, прошедшее с момента установки
$ShortInstallDate = "{0:yyyy-MM-dd HH:MM}" -f ($InstallDate)
"Система установлена: $ShortInstallDate (Прошло $AfterInstalldays дней)"
```
`(Get-WmiObject win32_battery).estimatedChargeRemaining` заряд батареи в процентах \
`gwmi Win32_UserAccount` доменные пользователи \
`(gwmi Win32_SystemUsers).PartComponent` \
`Get-CimInstance -ClassName Win32_LogonSession` \
`Get-CimInstance -ClassName Win32_BIOS`
`gwmi -list -Namespace root\CIMV2\Terminalservices` \
`(gwmi -Class Win32_TerminalServiceSetting -Namespace root\CIMV2\TerminalServices).AllowTSConnections` \
`(gwmi -Class Win32_TerminalServiceSetting -Namespace root\CIMV2\TerminalServices).SetAllowTSConnections(1)` включить RDP
```
$srv = "localhost"
gwmi Win32_logicalDisk -ComputerName $srv | where {$_.Size -ne $null} | select @{
Label="Value"; Expression={$_.DeviceID}}, @{Label="AllSize"; Expression={
[string]([int]($_.Size/1Gb))+" GB"}},@{Label="FreeSize"; Expression={
[string]([int]($_.FreeSpace/1Gb))+" GB"}}, @{Label="Free%"; Expression={
[string]([int]($_.FreeSpace/$_.Size*100))+" %"}}
```
### NLA (Network Level Authentication)
`(gwmi -class "Win32_TSGeneralSetting" -Namespace root\cimv2\Terminalservices -Filter "TerminalName='RDP-tcp'").UserAuthenticationRequired` \
`(gwmi -class "Win32_TSGeneralSetting" -Namespace root\cimv2\Terminalservices -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(1)` включить NLA \
`Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name SecurityLayer` отобразить значение (2) \
`Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name UserAuthentication` отобразить значение (1) \
`Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name SecurityLayer -Value 0` изменить значение \
`Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name UserAuthentication -Value 0` \
`REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2` отключить на клиентском компьютере проверку версии CredSSP, если на целевом комьютере-сервере не установлены обновления KB4512509 от мая 2018 года
# Regedit
`Get-PSDrive` список всех доступных дисков/разделов, их размер и веток реестра \
`cd HKLM:\` HKEY_LOCAL_MACHINE \
`cd HKCU:\` HKEY_CURRENT_USER \
`Get-Item` получить информацию о ветке реестра \
`New-Item` создать новый раздел реестра \
`Remove-Item` удалить ветку реестра \
`Get-ItemProperty` получить значение ключей/параметров реестра (это свойства ветки реестра, аналогично свойствам файла) \
`Set-ItemProperty` изменить название или значение параметра реестра \
`New-ItemProperty` создать параметр реестра \
`Remove-ItemProperty` удалить параметр
`Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select DisplayName` список установленных программ \
`Get-Item HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000002` посмотреть содержимое Items \
`(Get-ItemProperty HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000002)."New Signature"` отобразить значение (Value) свойства (Property) Items \
`$reg_path = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000002"` \
`$sig_name = "auto"` \
`Set-ItemProperty -Path $reg_path -Name "New Signature" -Value $sig_name` изменить или добавить в корне ветки (Path) свойство (Name) со значением (Value) \
`Set-ItemProperty -Path $reg_path -Name "Reply-Forward Signature" -Value $sig_name`
```
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe]
"Debugger"="\"C:\\Windows\\System32\\Taskmgr.exe\""
```
# Performance
`lodctr /R` пересоздать счетчиков производительности из системного хранилища архивов (так же исправляет счетчики для CIM, например, для cpu Win32_PerfFormattedData_PerfOS_Processor и iops Win32_PerfFormattedData_PerfDisk_PhysicalDisk) \
`(Get-Counter -ListSet *).CounterSetName` вывести список всех доступных счетчиков производительности в системе \
`(Get-Counter -ListSet *memory*).Counter` поиск по wildcard-имени во всех счетчиках (включая дочернии) \
`Get-Counter "\Memory\Available MBytes"` объем свободной оперативной памяти \
`Get-Counter -cn $srv "\LogicalDisk(*)\% Free Space"` % свободного места на всех разделах дисков \
`(Get-Counter "\Process(*)\ID Process").CounterSamples` \
`Get-Counter "\Processor(_Total)\% Processor Time" –ComputerName $srv -MaxSamples 5 -SampleInterval 2` 5 проверок каждые 2 секунды \
`Get-Counter "\Процессор(_Total)\% загруженности процессора" -Continuous` непрерывно \
`(Get-Counter "\Процессор(*)\% загруженности процессора").CounterSamples`
`(Get-Counter -ListSet *интерфейс*).Counter` найти все счетчики \
`Get-Counter "\Сетевой интерфейс(*)\Всего байт/с"` отобразить все адаптеры (выбрать действующий по трафику)
```PowerShell
$WARNING = 25
$CRITICAL = 50
$TransferRate = ((Get-Counter "\\huawei-mb-x-pro\сетевой интерфейс(intel[r] wi-fi 6e ax211 160mhz)\всего байт/с"
).countersamples | select -ExpandProperty CookedValue)*8
$NetworkUtilisation = [math]::round($TransferRate/1000000000*100,2)
if ($NetworkUtilisation -gt $CRITICAL){
Write-Output "CRITICAL: $($NetworkUtilisation) % Network utilisation, $($TransferRate.ToString('N0')) b/s"
#exit 2
}
if ($NetworkUtilisation -gt $WARNING){
Write-Output "WARNING: $($NetworkUtilisation) % Network utilisation, $($TransferRate.ToString('N0')) b/s"
#exit 1
}
Write-Output "OK: $($NetworkUtilisation) % Network utilisation, $($TransferRate.ToString('N0')) b/s"
#exit 0
```
# SNMP
### Setup SNMP Service
`Install-WindowsFeature SNMP-Service,SNMP-WMI-Provider -IncludeManagementTools` установить роль SNMP и WMI провайдер через Server Manager \
`Get-WindowsFeature SNMP*` \
`Add-WindowsCapability -Online -Name SNMP.Client~~~~0.0.1.0` установить компонент Feature On Demand для Windows 10/11` \
`Get-Service SNMP*` \
`Get-NetFirewallrule -DisplayName *snmp* | ft` \
`Get-NetFirewallrule -DisplayName *snmp* | Enable-NetFirewallRule`
### Setting SNMP Service via Regedit
Agent: \
`New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\RFC1156Agent" -Name "sysContact" -Value "lifailon-user"` создать (New) или изменить (Set) \
`New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\RFC1156Agent" -Name "sysLocation" -Value "plex-server"`
Security: \
`New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\TrapConfiguration\public"` создать новый community string \
`New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities" -Name "public" -Value 16` назначить права на public \
`1 — NONE` \
`2 — NOTIFY` позволяет получать SNMP ловушки \
`4 — READ ONLY` позволяет получать данные с устройства \
`8 — READ WRITE` позволяет получать данные и изменять конфигурацию устройства \
`16 — READ CREATE` позволяет читать данные, изменять и создавать объекты \
`New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers" -Name "1" -Value "192.168.3.99"` от кого разрешено принимать запросы \
`Get-Service SNMP | Restart-Service`
### snmpwalk
`snmpwalk -v 2c -c public 192.168.3.100` \
`snmpwalk -v 2c -c public -O e 192.168.3.100`
### Modules
`Install-Module -Name SNMP` \
`Get-SnmpData -IP 192.168.3.100 -OID 1.3.6.1.2.1.1.4.0 -UDPport 161 -Community public` \
`(Get-SnmpData -IP 192.168.3.100 -OID 1.3.6.1.2.1.1.4.0).Data` \
`Invoke-SnmpWalk -IP 192.168.3.100 -OID 1.3.6.1.2.1.1` пройтись по дереву OID \
`Invoke-SnmpWalk -IP 192.168.3.100 -OID 1.3.6.1.2.1.25.6.3.1.2` список установленного ПО \
`Invoke-SnmpWalk -IP 192.168.3.100 -OID 1.3.6.1.2.1.25.2.3.1` список разделов и памяти (C: D: Virtual Memory и Physical Memory) \
`Set-SnmpData` изменение данных на удаленном устройстве
`Install-Module -Name SNMPv3` \
`Invoke-SNMPv3Get` получение данных по одному OID \
`Invoke-SNMPv3Set` изменение данных \
`Invoke-SNMPv3Walk` обход по дереву OID \
`Invoke-SNMPv3Walk -UserName lifailon -Target 192.168.3.100 -AuthSecret password -PrivSecret password -OID 1.3.6.1.2.1.1 -AuthType MD5 -PrivType AES128`
### Lextm.SharpSnmpLib
https://api.nuget.org/v3-flatcontainer/lextm.sharpsnmplib/12.5.2/lextm.sharpsnmplib.12.5.2.nupkg \
`Add-Type -LiteralPath "$home\Desktop\lextm.sharpsnmplib-12.5.2\net471\SharpSnmpLib.dll"`
```PowerShell
$port = 161
$OID = "1.3.6.1.2.1.1.4.0"
$variableList = New-Object Collections.Generic.List[Lextm.SharpSnmpLib.Variable]
$variableList.Add([Lextm.SharpSnmpLib.Variable]::new([Lextm.SharpSnmpLib.ObjectIdentifier]::new($OID)))
$timeout = 3000
[Net.IPAddress]$ip = "192.168.3.100"
$endpoint = New-Object Net.IpEndPoint $ip, $port
$Community = "public"
[Lextm.SharpSnmpLib.VersionCode]$Version = "V2"
$message = [Lextm.SharpSnmpLib.Messaging.Messenger]::Get(
$Version,
$endpoint,
$Community,
$variableList,
$TimeOut
)
$message.Data.ToString()
```
### Walk
```PowerShell
[Lextm.SharpSnmpLib.ObjectIdentifier]$OID = "1.3.6.1.2.1.1" # дерево или конечный OID
$WalkMode = [Lextm.SharpSnmpLib.Messaging.WalkMode]::WithinSubtree # режим обхода по дереву
$results = New-Object Collections.Generic.List[Lextm.SharpSnmpLib.Variable]
$message = [Lextm.SharpSnmpLib.Messaging.Messenger]::Walk(
$Version,
$endpoint,
$Community,
$OID,
$results,
$TimeOut,
$WalkMode
)
$results
$results2 = @()
foreach ($d in $results) {
$results2 +=[PSCustomObject]@{'ID'=$d.id.ToString();'Data'=$d.Data.ToString()} # перекодировать вывод построчно в строку
}
$results2
```
# Zabbix
### Zabbix Agent Deploy
```PowerShell
$url = "https://cdn.zabbix.com/zabbix/binaries/stable/6.4/6.4.5/zabbix_agent2-6.4.5-windows-amd64-static.zip"
$path = "$home\Downloads\zabbix-agent2-6.4.5.zip"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($url, $path)` скачать файл
Expand-Archive $path -DestinationPath "C:\zabbix-agent2-6.4.5\"` разархивировать
Remove-Item $path` удалить архив
New-NetFirewallRule -DisplayName "Zabbix-Agent" -Profile Any -Direction Inbound -Action Allow -Protocol TCP -LocalPort 10050,10051` открыть порты в FW
$Zabbix_Server = "192.168.3.102"
$conf = "C:\zabbix-agent2-6.4.5\conf\zabbix_agent2.conf"
$cat = cat $conf
$rep = $cat -replace "Server=.+","Server=$Zabbix_Server"
$rep | Select-String Server=
$rep > $conf
$exe = "C:\zabbix-agent2-6.4.5\bin\zabbix_agent2.exe"
.$exe --config $conf --install` установить службу
Get-Service *Zabbix*Agent* | Start-Service` запустить службу
#.$exe --config $conf --uninstall` удалить службу
```
### zabbix_sender
Создать host - задать произвольное имя (powershell-host) и добавить в группу \
Создать Items: \
Name: Service Count \
Type: Zabbix trapper \
Key: service.count \
Type of Information: Numeric
```PowerShell
$path = "C:\zabbix-agent2-6.4.5\bin"
$scount = (Get-Service).Count
.$path\zabbix_sender.exe -z 192.168.3.102 -s "powershell-host" -k service.count -o $scount
```
### zabbix_get
`apt install zabbix-get` \
`nano /etc/zabbix/zabbix_agentd.conf` \
`Server=127.0.0.1,192.168.3.102,192.168.3.99` добавить сервера для получения данных zabbix_get с агента (как их запрашивает сервер)
`.$path\zabbix_get -s 192.168.3.101 -p 10050 -k agent.version` проверить версию агента \
`.$path\zabbix_get -s 192.168.3.101 -p 10050 -k agent.ping` 1 - ok \
`.$path\zabbix_get -s 192.168.3.101 -p 10050 -k net.if.discovery` список сетевых интерфейсов \
`.$path\zabbix_get -s 192.168.3.101 -p 10050 -k net.if.in["ens33"]` \
`.$path\zabbix_get -s 192.168.3.101 -p 10050 -k net.if.out["ens33"]`
### UserParameter
`UserParameter=process.count,powershell -Command "(Get-Process).Count"` \
`UserParameter=process.vm[*],powershell -Command "(Get-Process $1).ws"`
Test: \
`C:\zabbix-agent2-6.4.5\bin\zabbix_get.exe -s 127.0.0.1 -p 10050 -k process.count` \
`C:\zabbix-agent2-6.4.5\bin\zabbix_get.exe -s 127.0.0.1 -p 10050 -k process.vm[zabbix_agent2] `\
`C:\zabbix-agent2-6.4.5\bin\zabbix_get.exe -s 127.0.0.1 -p 10050 -k process.vm[powershell]`
Создать новые Items: \
key: `process.count` \
key: `process.vm[zabbix_agent2]`
### Include
- Добавить параметр Include для включения конфигурационных файлов подключаемых плагинов
`'Include=.\zabbix_agent2.d\plugins.d\*.conf' >> C:\zabbix-agent2-6.4.5\conf\zabbix_agent2.conf`
- Создать конфигурационный файл с пользовательскими параметрами в каталоге, путь к которому указан в zabbix_agentd.conf \
`'UserParameter=Get-Query-Param[*],powershell.exe -noprofile -executionpolicy bypass -File C:\zabbix-agent2-6.4.5\conf\zabbix_agent2.d\scripts\User-Sessions\Get-Query-Param.ps1 $1' > C:\zabbix-agent2-6.4.5\conf\zabbix_agent2.d\plugins.d\User-Sessions.conf`
- Поместить скрипт Get-Query-Param.ps1 в каталог, путь к которому указан в User-Sessions.conf. Скрипт содержим пользовательские параметры, которые он принимает от Zabbix сервера для передачи их в функции скрипта.
```PowerShell
Param([string]$select)
if ($select -eq "ACTIVEUSER") {
(Get-Query | where status -match "Active").User
}
if ($select -eq "INACTIVEUSER") {
(Get-Query | where status -match "Disconnect").User
}
if ($select -eq "ACTIVECOUNT") {
(Get-Query | where status -match "Active").Status.Count
}
if ($select -eq "INACTIVECOUNT") {
(Get-Query | where status -match "Disconnect").Status.Count
}
```
- Проверить работу скрипта:
`$path = "C:\zabbix-agent2-6.4.5\conf\zabbix_agent2.d\scripts\User-Sessions"` \
`.$path\Get-Query-Param.ps1 ACTIVEUSER` \
`.$path\Get-Query-Param.ps1 INACTIVEUSER` \
`.$path\Get-Query-Param.ps1 ACTIVECOUNT` \
`.$path\Get-Query-Param.ps1 INACTIVECOUNT`
- Создать Items с ключами:
`Get-Query-Param[ACTIVEUSER]` Type: Text \
`Get-Query-Param[INACTIVEUSER]` Type: Text \
`Get-Query-Param[ACTIVECOUNT]` Type: Int \
`Get-Query-Param[INACTIVECOUNT]` Type: Int
- Макросы:
`{$ACTIVEMAX} = 16` \
`{$ACTIVEMIN} = 0`
- Триггеры:
`last(/Windows-User-Sessions/Get-Query-Param[ACTIVECOUNT])>{$ACTIVEMAX}` \
`min(/Windows-User-Sessions/Get-Query-Param[ACTIVECOUNT],24h)={$ACTIVEMIN}`
### zabbix_agent2.conf
```
# Агент может работать в пассивном (сервер забирает сам информацию) и активном режиме (агент сам отправляет):
Server=192.168.3.102
ServerActive=192.168.3.102
# Требуется указать hostname для ServerActive:
Hostname=huawei-book-01
# Если не указано, используется для генерации имени хоста (игнорируется, если имя хоста определено):
# HostnameItem=system.hostname
# Как часто обновляется список активных проверок, в секундах (Range: 60-3600):
RefreshActiveChecks=120
# IP-адрес источника для исходящих соединений:
# SourceIP=
# Агент будет слушать на этом порту соединения с сервером (Range: 1024-32767):
# ListenPort=10050
# Список IP-адресов, которые агент должен прослушивать через запятую
# ListenIP=0.0.0.0
# Агент будет прослушивать этот порт для запросов статуса HTTP (Range: 1024-32767):
# StatusPort=
ControlSocket=\\.\pipe\agent.sock
# Куда вести журнал (file/syslog/console):
LogType=file
LogFile=C:\zabbix-agent2-6.4.5\zabbix_agent2.log
# Размер лога от 0-1024 MB (0 - отключить автоматическую ротацию логов)
LogFileSize=100
# Уровень логирования. 4 - для отладки (выдает много информации)
DebugLevel=4
```
### API Token
https://www.zabbix.com/documentation/current/en/manual/api/reference
`$ip = "192.168.3.102"` \
`$url = "http://$ip/zabbix/api_jsonrpc.php"`
```PowerShell
$data = @{
"jsonrpc"="2.0";
"method"="user.login";
"params"=@{
"username"="Admin";` в версии до 6.4 параметр "user"
"password"="zabbix";
};
"id"=1;
}
$token = (Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result
```
`$token = "2eefd25fdf1590ebcdb7978b5bcea1fff755c65b255da8cbd723181b639bb789"` сгенерировать токен в UI (http://192.168.3.102/zabbix/zabbix.php?action=token.list)
### user.get
```PowerShell
$data = @{
"jsonrpc"="2.0";
"method"="user.get";
"params"=@{
};
"auth"=$token;
"id"=1;
}
$users = (Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result
```
### problem.get
```PowerShell
$data = @{
"jsonrpc"="2.0";
"method"="problem.get";
"params"=@{
};
"auth"=$token;
"id"=1;
}
(Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result
```
### host.get
Получить список всех хостов (имя и id)
https://www.zabbix.com/documentation/current/en/manual/api/reference/host
host.create - creating new hosts \
host.delete - deleting hosts \
host.get - retrieving hosts \
host.massadd - adding related objects to hosts \
host.massremove - removing related objects from hosts \
host.massupdate - replacing or removing related objects from hosts \
host.update - updating hosts
```PowerShell
$data = @{
"jsonrpc"="2.0";
"method"="host.get";
"params"=@{
"output"=@(` отфильтровать вывод
"hostid";
"host";
);
};
"id"=2;
"auth"=$token;
}
$hosts = (Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result
$host_id = $hosts[3].hostid` забрать id хоста по индексу
```
### item.get
Получить id элементов данных по наименованию ключа для конкретного хоста
```PowerShell
$data = @{
"jsonrpc"="2.0";
"method"="item.get";
"params"=@{
"hostids"=@($host_id);` отфильтровать по хосту
};
"auth"=$token;
"id"=1;
}
$items = (Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result
$items_id = ($items | where key_ -match system.uptime).itemid` забрать id элемента данных
```
### history.get
Получить всю историю элемента данных по его id
```PowerShell
$data = @{
"jsonrpc"="2.0";
"method"="history.get";
"params"=@{
"hostids"=@($host_id); ` фильтрация по хосту
"itemids"=@($items_id);` фильтрация по элементу данных
};
"auth"=$token;
"id"=1;
}
$items_data_uptime = (Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result` получить все данные по ключу у конкретного хоста
```
### Convert Secconds To TimeSpan and DateTime
`$sec = $items_data_uptime.value`
```PowerShell
function ConvertSecondsTo-TimeSpan {
param (
$insec
)
$TimeSpan = [TimeSpan]::fromseconds($insec)
"{0:dd' day 'hh\:mm\:ss}" -f $TimeSpan
}
```
`$UpTime = ConvertSecondsTo-TimeSpan $sec[-1]`
### Convert From Unix Time
`$time = $items_data_uptime.clock`
```PowerShell
function ConvertFrom-UnixTime {
param (
$intime
)
$EpochTime = [DateTime]"1/1/1970"
$TimeZone = Get-TimeZone
$UTCTime = $EpochTime.AddSeconds($intime)
$UTCTime.AddMinutes($TimeZone.BaseUtcOffset.TotalMinutes)
}
```
`$GetDataTime = ConvertFrom-UnixTime $time[-1]`
`($hosts | where hostid -eq $host_id).host` получить имя хоста \
`$UpTime` последнее полученное значение времени работы хоста \
`$GetDataTime` время последнего полученного значения
# pki
`New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "$env:computername" -FriendlyName "Test Certificate" -NotAfter (Get-Date).AddYears(5)` создать самоподписанный сертификат (в LocalMachine\My - Сертификаты компьютера\Личное) с сроком действия 5 лет
`Get-ChildItem -Path Cert:\CurrentUser\Root\` список всех установленных сертификатов в хранилище Доверенные корневые ЦС Текущего пользователя \
`Get-ChildItem -Path Cert:\CurrentUser\My\` список самозаверяющих сертификатов в Личное хранилище Текущего пользователя \
`Get-ChildItem -Path Cert:\LocalMachine\My\` список самозаверяющих сертификатов в Личное хранилище Локального компьютера \
`Get-ChildItem -Path Cert:\LocalMachine\My\ | select NotBefore,NotAfter,Thumbprint,Subject` срок действия сертификата \
`Get-ChildItem -Path Cert:\LocalMachine\My\ | where Thumbprint -eq D9356FB774EE0E6206B7D5B59B99102CA5B17BDA` поиск сертификат по отпечатку
`Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificates\My\Certificates\` сертификаты в файловой системе, каждый файл соответствует сертификату, установленному в личном хранилище текущего пользователя \
`Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificates\My\Keys\` ссылки на объекты закрытых ключей, созданных поставщиком хранилища ключей (KSP) \
`Get-ChildItem -Path HKCU:\Software\Microsoft\SystemCertificates\CA\Certificates | ft -AutoSize` список сертификатов в реестре вошедшего в систему пользователя
`$cert = (Get-ChildItem -Path Cert:\CurrentUser\My\)[1]` выбрать сертификат \
`$cert | Remove-Item` удалить сертификат
`Export-Certificate -FilePath $home\Desktop\certificate.cer -Cert $cert` экспортировать сертификат \
`$cert.HasPrivateKey` проверить наличие закрытого ключа \
`$pass = "password" | ConvertTo-SecureString -AsPlainText -Force` создать пароль для шифрования закрытого ключа \
`Export-PfxCertificate -FilePath $home\Desktop\certificate.pfx -Password $pass -Cert $certificate` экспортировать сертификат с закрытым ключем
`Import-Certificate -FilePath $home\Desktop\certificate.cer -CertStoreLocation Cert:\CurrentUser\My` импортировать сертификат \
`Import-PfxCertificate -Exportable -Password $pass -CertStoreLocation Cert:\CurrentUser\My -FilePath $home\Desktop\certificate.pfx`
# OpenSSL
```PowerShell
Invoke-WebRequest -Uri https://slproweb.com/download/Win64OpenSSL_Light-3_1_1.msi -OutFile $home\Downloads\OpenSSL-Light-3.1.1.msi
Start-Process $home\Downloads\OpenSSL-Light-3.1.1.msi -ArgumentList '/quiet' -Wait` установить msi пакет в тихом режиме (запуск от имени Администратора)
rm $home\Downloads\OpenSSL-Light-3.1.1.msi
cd "C:\Program Files\OpenSSL-Win64\bin"
```
- Изменить пароль для PFX \
`openssl pkcs12 -in "C:\Cert\domain.ru.pfx" -out "C:\Cert\domain.ru.pem" -nodes` экспортируем имеющийся сертификат и закрытый ключ в .pem-файл без пароля с указанием текущего пароля \
`openssl pkcs12 -export -in "C:\Cert\domain.ru.pem" -out "C:\Cert\domain.ru_password.pfx" -nodes` конвертируем .pem обратно в .pfx c указанием нового пароля
- Конвертация из закрытого и открытого ключа PEM в PFX \
`openssl pkcs12 -export -in "C:\tmp\vpn\vpn.itproblog.ru-crt.pem" -inkey "C:\tmp\vpn\vpn.itproblog.ru-key.pem" -out "C:\tmp\vpn\vpn.iiproblog.ru.pfx"` \
in – путь до файла с открытым ключом \
inkey – путь до файла с закрытым ключом \
out – путь до файла, в который будет конвертирован сертификат (pfx)
- Конвертация PFX в CRT \
`openssl pkcs12 -in "C:\OpenSSL-Win64\bin\_.domain.ru.pfx" -clcerts -out "C:\OpenSSL-Win64\bin\_.domain.ru.crt"` указывается текущий и 2 раза новый пароль PEM pass phrase (файл содержит EGIN CERTIFICATE и BEGIN ENCRYPTED PRIVATE KEY) \
`openssl pkcs12 -in "C:\OpenSSL-Win64\bin\_.domain.ru.pfx" -clcerts -nokeys -out "C:\OpenSSL-Win64\bin\_.domain.ru.crt"` без ключа, получить открытую часть (файл содержит только EGIN CERTIFICATE)
- Конвертация PFX в KEY \
`openssl pkcs12 -in "C:\OpenSSL-Win64\bin\_.domain.ru.pfx" -nocerts -out "C:\OpenSSL-Win64\bin\_.domain.ru.key"` файл содержит только BEGIN ENCRYPTED PRIVATE KEY
- Снять пароль к закрытого ключа .key \
`openssl rsa -in "C:\OpenSSL-Win64\bin\_.domain.ru.key" -out "C:\OpenSSL-Win64\bin\_.domain.ru-decrypted.key"`
- CRT и KEY в PFX: \
`openssl pkcs12 -inkey certificate.key -in certificate.crt -export -out certificate.pfx`
# OpenVPN
`Invoke-WebRequest -Uri https://swupdate.openvpn.org/community/releases/OpenVPN-2.6.5-I001-amd64.msi -OutFile $home\Downloads\OpenVPN-2.6.5.msi` \
`Start-Process $home\Downloads\OpenVPN-2.6.5.msi -ArgumentList '/quiet /SELECT_OPENSSL_UTILITIES=1' -Wait` \
`msiexec /i $home\Downloads\OpenVPN-2.6.5.msi ADDLOCAL=EasyRSA /passive /quiet # установить отдельный компонент EasyRSA Certificate Management Scripts` \
`# msiexec /i $home\Downloads\OpenVPN-2.6.5.msi ADDLOCAL=OpenVPN.Service,Drivers,Drivers.Wintun,OpenVPN,OpenVPN.GUI,OpenVPN.GUI.OnLogon,EasyRSA /passive` выборочная установка \
`# Invoke-WebRequest -Uri https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.5/EasyRSA-3.1.5-win64.zip -OutFile $home\Downloads\EasyRSA-3.1.5.zip` скачать отдельный пакет EasyRSA \
`rm $home\Downloads\OpenVPN-2.6.5.msi`
`cd "C:\Program Files\OpenVPN\easy-rsa"` \
`Copy-Item vars.example vars` файл конфигурации для EasyRSA
```
set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI"
set_var EASYRSA_REQ_COUNTRY "RU"
set_var EASYRSA_REQ_PROVINCE "MSK"
set_var EASYRSA_REQ_CITY "MSK"
set_var EASYRSA_REQ_ORG "FAILON.NET"
set_var EASYRSA_REQ_EMAIL "lifailon@domain.ru"
set_var EASYRSA_REQ_OU "IT"
#set_var EASYRSA_KEY_SIZE 2048
#set_var EASYRSA_CA_EXPIRE 3650
#set_var EASYRSA_CERT_EXPIRE 825
```
`.\EasyRSA-Start.bat` среда EasyRSA Shell \
`easyrsa init-pki` инициализация PKI, создает директорию: C:\Program Files\OpenVPN\easy-rsa\pki и читает переменные файла \easy-rsa\vars \
`easyrsa build-ca` генерация корневого CA с указанием пароля и произвольное имя сервера (\pki\ca.crt и \pki\private\ca.key) \
`easyrsa gen-req server nopass` генерация запроса сертификата и ключ для сервера OpenVPN - yes (\pki\reqs\server.req и \pki\private\server.key) \
`easyrsa sign-req server server` подписать запрос на выпуск сертификата сервера с помощью CA - yes (\pki\issued\server.crt) \
`easyrsa gen-dh` создать ключ Диффи-Хеллмана (\pki\dh.pem) \
`easyrsa gen-req client1` nopass` генерация запроса сертификата и ключ для клиента OpenVPN (\pki\reqs\client1.req и \pki\private\client1.key)` \
`easyrsa sign-req client client1` подписать запрос на выпуск сертификата клиента с помощью CA - yes (\pki\issued\client1.crt) \
`easyrsa revoke client1` отозвать сертификат пользователя \
`openssl rsa -in "C:\Program Files\OpenVPN\easy-rsa\pki\private\client1.key" -out "C:\Program Files\OpenVPN\easy-rsa\pki\private\client1_nopass.key"` снять защиту паролем для ключа (BEGIN ENCRYPTED PRIVATE KEY -> BEGIN PRIVATE KEY) \
`exit` \
`cd "C:\Program Files\OpenVPN\bin"` \
`.\openvpn --genkey secret ta.key` генерация ключа tls-auth (\bin\ta.key) \
`Move-Item "C:\Program Files\OpenVPN\bin\ta.key" "C:\Program Files\OpenVPN\easy-rsa\pki\"`
### server.ovpn
`# Copy-Item "C:\Program Files\OpenVPN\sample-config\server.ovpn" "C:\Program Files\OpenVPN\config-auto\server.ovpn"` \
`New-Item -ItemType File -Path "C:\Program Files\OpenVPN\config-auto\server.ovpn"`
```
port 1194
proto udp
# Что именно инкапсулировать в туннеле (ethernet фреймы - tap или ip пакеты - tun)
dev tun
ca "C:\\Program Files\\OpenVPN\\easy-rsa\\pki\\ca.crt"
cert "C:\\Program Files\\OpenVPN\\easy-rsa\\pki\\issued\\server.crt"
key "C:\\Program Files\\OpenVPN\\easy-rsa\\pki\\private\\server.key"
dh "C:\\Program Files\\OpenVPN\\easy-rsa\\pki\\dh.pem"
server 192.168.4.0 255.255.255.0
# Хранит список сопоставления ip для клиентов, что бы назначить тот же адрес при перезапуске сервера
# ifconfig-pool-persist "C:\\Program Files\\OpenVPN\\dhcp-client-list.txt"
# Разрешить клиентам подключаться под одним ключом
# duplicate-cn
# max-clients 30
# Разрешить обмен трафиком между клиентами
client-to-client
# compress
tls-auth "C:\\Program Files\\OpenVPN\\easy-rsa\\pki\\ta.key" 0
cipher AES-256-GCM
keepalive 20 60
# Не перечитавать файлы ключей при перезапуске туннеля
persist-key
# Оставляет без изменения устройства tun/tap при перезапуске OpenVPN
persist-tun
status "C:\\Program Files\\OpenVPN\\log\\status.log"
log "C:\\Program Files\\OpenVPN\\log\\openvpn.log"
verb 3
mute 20
windows-driver wintun
# Открыть доступ к подсети за сервером
push "route 192.168.3.0 255.255.255.0"
push "route 192.168.4.0 255.255.255.0"
# Завернуть все запросы клиента (в том числе Интернет трафик) на OpenVPN сервер
# push "redirect-gateway def1"
# push "dhcp-option DNS 192.168.3.101"
# push "dhcp-option DOMAIN failon.net"
```
`New-NetFirewallRule -DisplayName "AllowOpenVPN-In" -Direction Inbound -Protocol UDP –LocalPort 1194 -Action Allow` на сервере \
`New-NetFirewallRule -DisplayName "AllowOpenVPN-Out" -Direction Outbound -Protocol UDP –LocalPort 1194 -Action Allow` на клиенте \
`Get-Service *openvpn* | Restart-Service`
### client.ovpn
`# Copy-Item "C:\Program Files\OpenVPN\sample-config\client.ovpn" "C:\Program Files\OpenVPN\config-auto\client.ovpn"` \
`New-Item -ItemType File -Path "C:\Program Files\OpenVPN\config-auto\client.ovpn"`
```
client
dev tun
proto udp
remote 26.115.154.67 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client1.crt
key client1.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-GCM
connect-retry-max 25
# Использовать драйвер wintun и полный путь до сертификатов при использовании openvpn gui
windows-driver wintun
verb 3
```
### Client
`iwr -Uri https://openvpn.net/downloads/openvpn-connect-v3-windows.msi -OutFile "$home\downloads\OpenVPN-Connect-3.msi"` \
Передать конфигурацию и ключи: \
`client.ovpn` \
`ca.crt` \
`dh.pem` \
`ta.key` \
`client1.crt` \
`client1.key`
# Route
`Get-Service RemoteAccess | Stop-Service` \
`Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "IPEnableRouter" -Value 1` включает IP маршрутизацию \
`(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters").IPEnableRouter` \
`Get-NetIPInterface | select ifIndex,InterfaceAlias,AddressFamily,ConnectionState,Forwarding | ft` отобразить сетевые интерфейсы \
`Set-NetIPInterface -ifIndex 13 -Forwarding Enabled` включить переадресацию на интерфейсе
`sysctl net.ipv4.ip_forward=1` \
`echo "sysctl net.ipv4.ip_forward = 1" >> /etc/sysctl.conf`
`Get-NetRoute` \
`New-NetRoute -DestinationPrefix "192.168.3.0/24" -NextHop "192.168.4.1" -InterfaceIndex 8` \
`route -p add 192.168.3.0 mask 255.255.255.0 192.168.4.1 metric 1` \
`route -p change 192.168.3.0 mask 255.255.255.0 192.168.4.1 metric 2` \
`route -p add 192.168.3.0 mask 255.255.255.0 192.168.4.1 metric 1 if 7` указать номер сетевого интерфейса на который необходимо посылать пакет (Wintun Userspace Tunnel) \
`route print -4` \
`route delete 192.168.3.0`
`tracert 192.168.3.101` с 192.168.4.6
```
1 17 ms * 22 ms 192.168.4.1
2 12 ms 13 ms 14 ms 192.168.3.101
```
`route add -net 192.168.4.0 netmask 255.255.255.0 gw 192.168.3.100` \
`route -e`
`traceroute 192.168.4.6` с 192.168.3.101
```
1 192.168.3.100 (192.168.3.100) 0.148 ms 0.110 ms 0.106 ms
2 192.168.4.6 (192.168.4.6) 14.573 ms * *
```
`ping 192.168.3.101 -t` с 192.168.4.6 \
`tcpdump -n -i ens33 icmp` на 192.168.3.101
```
14:36:34.533771 IP 192.168.4.6 > 192.168.3.101: ICMP echo request, id 1, seq 2962, length 40 # отправил запрос
14:36:34.533806 IP 192.168.3.101 > 192.168.4.6: ICMP echo reply, id 1, seq 2962, length 40 # отправил ответ
```
# NAT
`Get-Command -Module NetNat` \
`New-NetNat -Name LocalNat -InternalIPInterfaceAddressPrefix "192.168.3.0/24"` \
`Add-NetNatStaticMapping -NatName LocalNat -Protocol TCP -ExternalIPAddress 0.0.0.0 -ExternalPort 80 -InternalIPAddress 192.168.3.102 -InternalPort 80` \
`Remove-NetNatStaticMapping -StaticMappingID 0` \
`Remove-NetNat -Name LocalNat`
# WireGuard
`Invoke-WebRequest "https://download.wireguard.com/windows-client/wireguard-amd64-0.5.3.msi" -OutFile "$home\Downloads\WireGuard-Client-0.5.3.msi"` \
`msiexec.exe /i "$home\Downloads\WireGuard-Client-0.5.3.msi" DO_NOT_LAUNCH=1 /qn` \
`Invoke-WebRequest "http://www.wiresock.net/downloads/wiresock-vpn-gateway-x64-1.1.4.1.msi" -OutFile "$home\Downloads\WireSock-VPN-Gateway-1.1.4.1.msi"` \
`msiexec.exe /i "http://www.wiresock.net/downloads/wiresock-vpn-gateway-x64-1.1.4.1.msi" /qn` \
`$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")` \
`wg-quick-config -add -start` \
`26.115.154.67:8181` \
`192.168.21.4/24` \
`Successfully saved client configuration: C:\ProgramData\NT KERNEL\WireSock VPN Gateway\wsclient_1.conf` \
`Successfully saved server configuration: C:\ProgramData\NT KERNEL\WireSock VPN Gateway\wiresock.conf` \
`get-service *wire*` \
`wg show` \
`wg-quick-config -add -restart` add client
wiresock.conf
```
[Interface]
PrivateKey = gCHC0g2JPwr6sXPiaOL4/KTkMyjN9TculrJUA/GORV8=
Address = 192.168.21.5/24
ListenPort = 8181
[Peer]
PublicKey = NoSxjew2RCHiUzI6mlahjd4I+0EcLsoYom/H01z91yU=
AllowedIPs = 192.168.21.6/32
```
wsclient_1.conf (добавить маршруты для клиента в AllowedIPs)
```
[Interface]
PrivateKey = yIpRQRmaGrrk9Y+49E8JhEpFmKzSeecvUAdeNgf1hUM=
Address = 192.168.21.6/24
DNS = 8.8.8.8, 1.1.1.1
MTU = 1420
[Peer]
PublicKey = Fp7674VSYeGj8CYt6RCKR7Qz1y/IKUXCw8ImOFhX3hk=
AllowedIPs = 192.168.21.0/24, 192.168.3.0/24
Endpoint = 26.115.154.67:8181
PersistentKeepalive = 25
```
# VpnClient
`Get-Command -Module VpnClient` \
`Add-VpnConnection -Name "vpn-failon" -ServerAddress "26.115.154.67" -TunnelType L2TP -L2tpPsk "123098" -EncryptionLevel "Required" -AuthenticationMethod MSChapv2 -RememberCredential -AllUserConnection –PassThru -Force` \
`-TunnelType PPTP/L2TP/SSTP/IKEv2/Automatic` \
`-L2tpPsk` использовать общий ключ для аутентификации (без параметра, для L2TP аутентификации используется сертификат) \
`-AuthenticationMethod Pap/Chap/MSChapv2/Eap/MachineCertificate` \
`-EncryptionLevel NoEncryption/Optional/Required/Maximum/Custom` \
`-SplitTunneling` заворачивать весь трафик через VPN-туннель (включение Use default gateway on remote network в настройках параметра VPN адаптера) \
`-UseWinlogonCredential` использовать учетные данные текущего пользователя для аутентификации на VPN сервере \
`-RememberCredential` разрешить сохранять учетные данные для VPN подключения (учетная запись и пароль сохраняются в диспетчер учетных данных Windows после первого успешного подключения) \
`-DnsSuffix domain.local` \
`-AllUserConnection` разрешить использовать VPN подключение для всех пользователей компьютера (сохраняется в конфигурационный файл: C:\ProgramData\Microsoft\Network\Connections\Pbk\rasphone.pbk)
`Install-Module -Name VPNCredentialsHelper` модуль для сохранения логина и пароля в Windows Credential Manager для VPN подключения \
`Set-VpnConnectionUsernamePassword -connectionname vpn-failon -username user1 -password password`
`rasdial "vpn-failon"` подключиться \
`Get-VpnConnection -AllUserConnection | select *` список VPN подключения, доступных для всех пользователей, найстройки и текущий статус подключения (ConnectionStatus) \
`Add-VpnConnectionRoute -ConnectionName vpn-failon -DestinationPrefix 192.168.3.0/24 –PassThru` динамически добавить в таблицу маршрутизации маршрут, который будет активен при подключении к VPN \
`Remove-VpnConnection -Name vpn-failon -AllUserConnection -Force` удалить
`Set-VpnConnection -Name "vpn-failon" -SplitTunneling $True` включить раздельное тунеллирование \
`Add-VpnConnectionRoute -ConnectionName "vpn-failon" -DestinationPrefix 172.22.22.0/24` настроить маршрутизацию к указанной подсети через VPN-соединение \
`(Get-VpnConnection -ConnectionName "vpn-failon").routes` отобразить таблицу маршрутизации для указанного соединения \
`Remove-VpnConnectionRoute -ConnectionName "vpn-failon" -DestinationPrefix "172.22.23.0/24"`
# Proxy
`$user = "lifailon"` \
`$pass = "Proxy"` \
`$SecureString = ConvertTo-SecureString $pass -AsPlainText -Force` \
`$Credential = New-Object System.Management.Automation.PSCredential($user, $SecureString)` \
`[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy("http://192.168.3.100:9090")` \
`[System.Net.Http.HttpClient]::DefaultProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials` \
`[System.Net.Http.HttpClient]::DefaultProxy.Credentials = $Credential` \
`Invoke-RestMethod http://ifconfig.me/ip` \
`Invoke-RestMethod https://kinozal.tv/rss.xml`
# OpenSSH
`Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Client*'` \
`Add-WindowsCapability -Online -Name OpenSSH.Client*` \
`dism /Online /Add-Capability /CapabilityName:OpenSSH.Client~~~~0.0.1.0` \
`iwr https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.2.2.0p1-Beta/OpenSSH-Win64-v9.2.2.0.msi -OutFile $home\Downloads\OpenSSH-Win64-v9.2.2.0.msi` скачать \
`msiexec /i $home\Downloads\OpenSSH-Win64-v9.2.2.0.msi` установить msi пакет \
`Set-Service sshd -StartupType Automatic` \
`Get-NetTCPConnection | where LocalPort -eq 22` \
`New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22` \
`Get-NetFirewallRule -Name *ssh*` \
`Start-Process notepad++ C:\Programdata\ssh\sshd_config` конфигурационный файл \
`GSSAPIAuthentication yes` включить Kerberos аутентификацию (через AD) \
`SyslogFacility LOCAL0` включить локальное ведение журнала в файл (C:\ProgramData\ssh\logs\sshd.log) \
`LogLevel INFO` \
`Restart-Service sshd` \
`ssh -K $srv` выполнить Kerberos аутентификацию \
`ssh Lifailon@192.168.3.99 -p 22` \
`pwsh -command Get-Service` \
`ssh -L 3101:192.168.3.101:22 -R 3101:192.168.3.101:22 lifailon@192.168.3.101 -p 22` SSH Tunnel lifailon@localhost:3101 -> 192.168.3.101:3101
# WinRM
`Enter-PSSession -ComputerName $srv` подключиться к PowerShell сессии через PSRemoting. Подключение возможно только по FQDN-имени \
`Invoke-Command $srv -ScriptBlock {Get-ComputerInfo}` выполнение команды через PSRemoting \
`$session = New-PSSession $srv` открыть сессию \
`Get-PSSession` отобразить активные сессии \
`icm -Session $session {$srv = $using:srv}` передать переменную текущей сессии ($using) в удаленную \
`Disconnect-PSSession $session` закрыть сессию \
`Remove-PSSession $session` удалить сессию \
`Import-Module -Name ActiveDirectory -PSSession $srv` импортировать модуль с удаленного компьютера в локальную сессию
### Windows Remote Management Configuration
`winrm quickconfig -quiet` изменит запуск службы WinRM на автоматический, задаст стандартные настройки WinRM и добавить исключения для портов в fw \
`Enable-PSRemoting –Force` включить PowerShell Remoting, работает только для доменного и частного сетевых профилей Windows \
`Enable-PSRemoting -SkipNetworkProfileCheck -Force` для настройки компьютера в общей (public) сети (работает с версии powershell 6)
`$NetProfiles = Get-NetConnectionProfile` отобразить профили сетевых подключений \
`Set-NetConnectionProfile -InterfaceIndex $NetProfiles[1].InterfaceIndex -NetworkCategory Private` изменить тип сети для профиля (DomainAuthenticated/Public) \
`(Get-CimInstance -ClassName Win32_ComputerSystem).PartOfDomain` проверить, что компьютер добавлен в домен AD \
`Get-Service WinRM | Set-Service -StartupType AutomaticDelayedStart` отложенный запуск \
`Get-Service -Name winrm -RequiredServices` статус зависимых служб \
`New-NetFirewallRule -Profile Any -DisplayName "WinRM HTTP" -Direction Inbound -Protocol TCP -LocalPort 5985,5986` \
`Test-NetConnection $srv -port 5895` проверить порт \
`Test-WSMan $srv -ErrorAction Ignore` проверить работу WinRM на удаленном компьютере (игнорировать вывод ошибок для скрипта) или локально (localhost)
`$Cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "$env:computername" -FriendlyName "WinRM HTTPS Certificate" -NotAfter (Get-Date).AddYears(5)` создать самоподписанный сертификат \
`$Thumbprint = $Cert.Thumbprint` забрать отпечаток \
`New-Item -Path WSMan:\Localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint $Thumbprint -Name WinRM_HTTPS_Listener -Force` создать прослушиватель \
`New-NetFirewallRule -DisplayName 'WinRM HTTPS' -Profile Domain,Private -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986` открыть порт в fw
```
$selector_set = @{
Address = "*"
Transport = "HTTPS"
}
$value_set = @{
CertificateThumbprint = "66ABFDA044D8C85135048186E2FDC0DBE6125163"
}
New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selector_set -ValueSet $value_set
```
`winrm get winrm/config` отобразить всю конфигурацию (Client/Service) \
`winrm get winrm/config/service/auth` конфигурация авторизации на сервере \
`winrm enumerate winrm/config/listener` текущая конфигурация прослушивателей WinRM (отображает отпечаток сертификата для HTTPS 5986) \
`Get-ChildItem -Path Cert:\LocalMachine\My\ | where Thumbprint -eq D9356FB774EE0E6206B7D5B59B99102CA5B17BDA | select *` информация о сертификате
`ls WSMan:\localhost\Client` конфигурацию клиента \
`ls WSMan:\localhost\Service` конфигурация сервера \
`ls WSMan:\localhost\Service\auth` список всех конфигураций аутентификации WinRM сервера \
`Set-Item -path WSMan:\localhost\Service\auth\basic -value $true` разрешить локальную аутентификацию к текущему серверу \
`ls HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN` настройки в реестре (например, для включения аудентификации в \Service\auth_basic = 1) \
`Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.* -Force` добавить доверенные хосты в конфигурацию на клиенте, чтобы работала Negotiate аутентификация через NTLM \
`Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.3.100 -Concatenate -Force` добавить второй компьютер \
`ls WSMan:\localhost\Client\TrustedHosts` \
`Set-Item WSMan:\localhost\Client\AllowUnencrypted $true` включить передача незашифрованных данных конфигурации клиента \
`Set-Item WSMan:\localhost\Service\AllowUnencrypted $true` включить передача незашифрованных данных конфигурации сервера (необходимо быть в private сети)
`Get-PSSessionConfiguration` проверить, включен ли PSremoting и вывести список пользователей и групп, которым разрешено подключаться через WinRM \
`Set-PSSessionConfiguration -Name Microsoft.PowerShell -ShowSecurityDescriptorUI` назначить права доступа через дескриптор безопасности текущей сессии (до перезагруки) \
`(Get-PSSessionConfiguration -Name "Microsoft.PowerShell").SecurityDescriptorSDDL` получить настройки дескриптора в формате SDDL \
`Set-PSSessionConfiguration -Name Microsoft.PowerShell -SecurityDescriptorSDDL $SDDL` применить настройки дескриптора на другом компьютере без использования GUI \
`New-LocalUser "WinRM-Writer" -Password (ConvertTo-SecureString -AsPlainText "123098")` создать пользователя \
`Add-LocalGroupMember -Group "Remote Management Users" -Member "WinRM-Writer"` добавить пользователя WinRM-Writer в локальную группу доступа "Пользователи удаленного управления" \
`cmdkey /add:192.168.3.99 /user:WinRM-Writer /pass:123098` сохранить пароль в CredentialManager
`cmdkey /list` \
`Import-Module CredentialManager` \
`Add-Type -AssemblyName System.Web` \
`New-StoredCredential -Target 192.168.3.99 -UserName WinRM-Writer -Password 123098 -Comment WinRM` сохранить пароль в CredentialManager (из PS5) \
`Get-StoredCredential -AsCredentialObject` \
`$cred = Get-StoredCredential -Target 192.168.3.99` \
`Enter-PSSession -ComputerName 192.168.3.99 -Credential $cred -Authentication Negotiate` \
`Enter-PSSession -ComputerName 192.168.3.99 -Credential $cred -Authentication Basic -Port 5985` работает при отключении allowunencrypted на стороне сервера и клиента \
`winrs -r:http://192.168.3.100:5985/wsman -u:WinRM-Writer -p:123098 ipconfig` передать команду через winrs (-?) \
`winrs -r:https://192.168.3.100:5985/wsman -u:WinRM-Writer -p:123098 -ssl ipconfig` через https \
`pwsh -Command "Install-Module -Name PSWSMan"` установить модуль для использования в Linux системе
### Kerberos
`.\CheckMaxTokenSize.ps1 -Principals login -OSEmulation $true -Details $true` узнать размер токена пользователя в домене \
`Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters | select maxtokensize` максимальный размер токена на сервере \
`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters` изменить размера, если заголовок пакета аутентификации превышает 16 Кб (из за большого кол-ва групп) \
`MaxFieldLength увеличить до 0000ffff (65535)` \
`MaxRequestBytes увеличить до 0000ffff (65535)`
# DSC
`Import-Module PSDesiredStateConfiguration` \
`(Get-Module PSDesiredStateConfiguration).ExportedCommands` \
`Get-DscLocalConfigurationManager`
`Get-DscResource` \
`Get-DscResource -Name File -Syntax` https://learn.microsoft.com/ru-ru/powershell/dsc/reference/resources/windows/fileresource?view=dsc-1.1
`Ensure = Present` настройка должна быть включена (каталог должен присутствовать, процесс должен быть запущен, если нет – создать, запустить) \
`Ensure = Absent` настройка должна быть выключена (каталога быть не должно, процесс не должен быть запущен, если нет – удалить, остановить)
```PowerShell
Configuration TestConfiguraion
{
Ctrl+Space
}
Configuration DSConfigurationProxy
{
Node vproxy-01
{
File CreateDir
{
Ensure = "Present"
Type = "Directory"
DestinationPath = "C:\Temp"
}
Service StopW32time
{
Name = "w32time"
State = "Stopped"` Running
}
WindowsProcess RunCalc
{
Ensure = "Present"
Path = "C:\WINDOWS\system32\calc.exe"
Arguments = ""
}
Registry RegSettings
{
Ensure = "Present"
Key = "HKEY_LOCAL_MACHINE\SOFTWARE\MySoft"
ValueName = "TestName"
ValueData = "TestValue"
ValueType = "String"
}
# WindowsFeature IIS
# {
# Ensure = "Present"
# Name = "Web-Server"
# }
}
}
```
`$Path = (DSConfigurationProxy).DirectoryName` \
`Test-DscConfiguration -Path $Path | select *` ResourcesInDesiredState - уже настроено, ResourcesNotInDesiredState - не настроено (не соответствует) \
`Start-DscConfiguration -Path $Path` \
`Get-Job` \
`$srv = "vproxy-01"` \
`Get-Service -ComputerName $srv | ? name -match w32time # Start-Service` \
`icm $srv {Get-Process | ? ProcessName -match calc} | ft # Stop-Process -Force` \
`icm $srv {ls C:\ | ? name -match Temp} | ft` rm`
# Git
`git --version` \
`git config --global user.name "Lifailon"` добавить имя для коммитов \
`git config --global user.email "lifailon@yandex.ru"` \
`git config --global --edit` \
`ssh-keygen -t rsa -b 4096` \
`Get-Service | where name -match "ssh-agent" | Set-Service -StartupType Automatic` \
`Get-Service | where name -match "ssh-agent" | Start-Service` \
`Get-Service | where name -match "ssh-agent" | select Name,Status,StartType` \
`ssh-agent` \
`ssh-add C:\Users\Lifailon\.ssh\id_rsa` \
`cat ~\.ssh\id_rsa.pub | Set-Clipboard` copy to https://github.com/settings/keys \
`cd $home\Documents\Git` \
`git clone git@github.com:Lifailon/PowerShell-Commands` \
`cd PowerShell-Commands` \
`git grep powershell` поиск текста в файлах \
`git pull` синхронизировать изменения из хранилища \
`git status` отобразить статус изменений по файлам \
`git diff` отобразить изменения построчно \
`git add .` добавить (проиндексировать) изменения во всех файлах \
`git commit -m "added file and changed file"` сохранить изменения с комментарием \
`git push` синхронизировать локальные изменения с репозиторием \
`git branch dev` создать новую ветку \
`git switch dev` переключиться на другую ветку \
`git push --set-upstream origin dev` добавить ветку \
`git branch -d dev` удалить ветку \
`git diff rsa` сравнить файлы текущей ветки с файлами в указанной ветки rsa \
`git merge dev` слияние текущей ветки (rsa/master) с указанной (dev) \
`git log --oneline --all` лог коммитов \
`git log --graph` коммиты и следование веток \
`git show d01f09dead3a6a8d75dda848162831c58ca0ee13` отобразить подробный лог по номеру коммита \
`git checkout filename` откатить изменения, если не было команды add \
`git checkout d01f09dead3a6a8d75dda848162831c58ca0ee13` переключить локальные файлы рабочей копии на указанный коммит (изменить HEAD на указанный коммит) \
`git reset HEAD filename` откатить изменения последнего индекса, если был add но не было commit, тем самым вернуться до последней зафиксированный версии (коммита) и потом выполнить checkout \
`git reset --mixed HEAD filename` изменения, содержащиеся в отменяемом коммите, не должны исчезнуть, они будут сохранены в виде локальных изменений в рабочей копии \
`git restore filename` отменить все локальные изменения в рабочей копии \
`git restore --source d01f09dead3a6a8d75dda848162831c58ca0ee13 filename` восстановить файл на указанную версию по хэшу индентификатора коммита \
`git revert HEAD --no-edit` отменить последний коммит, без указания комментария (события записываются в git log) \
`git reset --hard d01f09dead3a6a8d75dda848162831c58ca0ee13` удалить все коммиты до указанного (и откатиться до него)
# Ansible
`apt -y update && apt -y upgrade` \
`apt -y install ansible` v2.10.8 \
`apt -y install ansible-core` v2.12.0 \
`apt -y install sshpass`
`ansible-galaxy collection install ansible.windows` установить коллекцию модулей \
`ansible-galaxy collection install community.windows` \
`ansible-galaxy collection list | grep windows` \
`ansible-config dump | grep DEFAULT_MODULE_PATH` путь хранения модулей
`apt-get -y install python-dev libkrb5-dev krb5-user` пакеты для Kerberos аутентификации \
`apt install python3-pip` \
`pip3 install requests-kerberos` \
`nano /etc/krb5.conf` настроить [realms] и [domain_realm] \
`kinit -C support4@domail.local` \
`klist`
`ansible --version` \
`config file = None` \
`nano /etc/ansible/ansible.cfg` файл конфигурации
```
[defaults]
inventory = /etc/ansible/hosts
# uncomment this to disable SSH key host checking
# Отключить проверку ключа ssh (для подключения используя пароль)
host_key_checking = False
```
`nano /etc/ansible/hosts`
```
[us]
pi-hole-01 ansible_host=192.168.3.101
zabbix-01 ansible_host=192.168.3.102
grafana-01 ansible_host=192.168.3.103
netbox-01 ansible_host=192.168.3.104
[all:vars]
ansible_ssh_port=2121
ansible_user=lifailon
ansible_password=123098
path_user=/home/lifailon
ansible_python_interpreter=/usr/bin/python3
[ws]
huawei-book-01 ansible_host=192.168.3.99
plex-01 ansible_host=192.168.3.100
[ws:vars]
ansible_port=5985
#ansible_port=5986
ansible_user=Lifailon
#ansible_user=support4@DOMAIN.LOCAL
ansible_password=123098
ansible_connection=winrm
ansible_winrm_scheme=http
ansible_winrm_transport=basic
#ansible_winrm_transport=kerberos
ansible_winrm_server_cert_validation=ignore
validate_certs=false
[win_ssh]
huawei-book-01 ansible_host=192.168.3.99
plex-01 ansible_host=192.168.3.100
[win_ssh:vars]
ansible_python_interpreter=C:\Users\Lifailon\AppData\Local\Programs\Python\Python311\` добавить переменную среды интерпритатора Python в Windows
ansible_connection=ssh
#ansible_shell_type=cmd
ansible_shell_type=powershell
```
`ansible-inventory --list` проверить конфигурацию (читает в формате JSON) или YAML (-y) с просмотром все применяемых переменных
# Modules
`ansible us -m ping` \
`ansible win_ssh -m ping` \
`ansible us -m shell -a "uptime && df -h | grep lv"` \
`ansible us -m setup | grep -iP "mem|proc"` информация о железе \
`ansible us -m apt -a "name=mc" -b` повысить привилегии sudo (-b) \
`ansible us -m service -a "name=ssh state=restarted enabled=yes" -b` перезапустить службу \
`echo "echo test" > test.sh` \
`ansible us -m copy -a "src=test.sh dest=/root mode=777" -b` \
`ansible us -a "ls /root" -b` \
`ansible us -a "cat /root/test.sh" -b`
`ansible-doc -l | grep win_` список всех модулей Windows (https://docs.ansible.com/ansible/latest/collections/ansible/windows/) \
`ansible ws -m win_ping` windows модуль \
`ansible ws -m win_ping -u WinRM-Writer` указать логин \
`ansible ws -m setup` собрать подробную информацию о системе \
`ansible ws -m win_whoami` информация о правах доступах, группах доступа \
`ansible ws -m win_shell -a '$PSVersionTable'` \
`ansible ws -m win_shell -a 'Get-Service | where name -match "ssh|winrm"'` \
`ansible ws -m win_service -a "name=sshd state=stopped"` \
`ansible ws -m win_service -a "name=sshd state=started"`
### win_shell (vars/debug)
`nano /etc/ansible/PowerShell-Vars.yml`
```
- hosts: ws
` Указать коллекцию модулей
collections:
- ansible.windows
` Задать переменные
vars:
SearchName: PermitRoot
tasks:
- name: Get port ssh
win_shell: |
Get-Content "C:\Programdata\ssh\sshd_config" | Select-String "{{SearchName}}"
` Передать вывод в переменную
register: command_output
- name: Output port ssh
` Вывести переменную на экран
debug:
var: command_output.stdout_lines
```
`ansible-playbook /etc/ansible/PowerShell-Vars.yml` \
`ansible-playbook /etc/ansible/PowerShell-Vars.yml --extra-vars "SearchName='LogLevel|Syslog'"` передать переменную
### win_powershell
`nano /etc/ansible/powershell-param.yml`
```
- hosts: ws
tasks:
- name: Run PowerShell script with parameters
ansible.windows.win_powershell:
parameters:
Path: C:\Temp
Force: true
script: |
[CmdletBinding()]
param (
[String]$Path,
[Switch]$Force
)
New-Item -Path $Path -ItemType Directory -Force:$Force
```
`ansible-playbook /etc/ansible/powershell-param.yml`
### win_chocolatey
`nano /etc/ansible/setup-adobe-acrobat.yml`
```
- hosts: ws
tasks:
- name: Install Acrobat Reader
win_chocolatey:
name: adobereader
state: present
```
`ansible-playbook /etc/ansible/setup-adobe-acrobat.yml`
`nano /etc/ansible/setup-openssh.yml`
```
- hosts: ws
tasks:
- name: install the Win32-OpenSSH service
win_chocolatey:
name: openssh
package_params: /SSHServerFeature
state: present
```
`ansible-playbook /etc/ansible/setup-openssh.yml`
### win_regedit
`nano /etc/ansible/win-set-shell-ssh-ps7.yml`
```
- hosts: ws
tasks:
- name: Set the default shell to PowerShell 7 for Windows OpenSSH
win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
` data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
data: 'C:\Program Files\PowerShell\7\pwsh.exe'
type: string
state: present
```
`ansible-playbook /etc/ansible/win-set-shell-ssh-ps7.yml`
### win_service
`nano /etc/ansible/win-service.yml`
```
- hosts: ws
tasks:
- name: Start service
win_service:
name: sshd
state: started
# state: stopped
# state: restarted
# start_mode: auto
```
`ansible-playbook /etc/ansible/win-service.yml`
### win_service_info
`nano /etc/ansible/get-service.yml`
```
- hosts: ws
tasks:
- name: Get info for a single service
win_service_info:
name: sshd
register: service_info
- name: Print returned information
ansible.builtin.debug:
var: service_info.services
```
`ansible-playbook /etc/ansible/get-service.yml`
### fetch/slurp
`nano /etc/ansible/copy-from-win-to-local.yml`
```
- hosts: ws
tasks:
- name: Retrieve remote file on a Windows host
# Скопировать файл из Windows-системы
ansible.builtin.fetch:
# Прочитать файл (передать в память в формате Base64)
# ansible.builtin.slurp:
src: C:\Telegraf\telegraf.conf
dest: /root/telegraf.conf
flat: yes
register: telegraf_conf
- name: Print returned information
ansible.builtin.debug:
msg: "{{ telegraf_conf['content'] | b64decode }}"
```
`ansible-playbook /etc/ansible/copy-from-win-to-local.yml`
### win_copy
`echo "Get-Service | where name -eq vss | Start-Service" > /home/lifailon/Start-Service-VSS.ps1` \
`nano /etc/ansible/copy-file-to-win.yml`
```
- hosts: ws
tasks:
- name: Copy file to win hosts
win_copy:
src: /home/lifailon/Start-Service-VSS.ps1
dest: C:\Users\Lifailon\Desktop\Start-Service-VSS.ps1
```
`ansible-playbook /etc/ansible/copy-file-to-win.yml`
`curl -OL https://github.com/PowerShell/PowerShell/releases/download/v7.3.6/PowerShell-7.3.6-win-x64.msi` \
`nano /etc/ansible/copy-file-to-win.yml`
```
- hosts: ws
tasks:
- name: Copy file to win hosts
win_copy:
src: /home/lifailon/PowerShell-7.3.6-win-x64.msi
dest: C:\Install\PowerShell-7.3.6.msi
```
`ansible-playbook /etc/ansible/copy-file-to-win.yml`
### win_command
`nano /etc/ansible/run-script-ps1.yml`
```
- hosts: ws
tasks:
- name: Run PowerShell Script
win_command: powershell -ExecutionPolicy ByPass -File C:\Users\Lifailon\Desktop\Start-Service-VSS.ps1
```
`ansible-playbook /etc/ansible/run-script-ps1.yml`
### win_package
`nano /etc/ansible/setup-msi-package.yml`
```
- hosts: ws
tasks:
- name: Install MSI Package
win_package:
# path: C:\Install\7z-23.01.msi
path: C:\Install\PowerShell-7.3.6.msi
arguments:
- /quiet
- /passive
- /norestart
```
`ansible-playbook /etc/ansible/setup-msi-package.yml`
### win_firewall_rule
`nano /etc/ansible/win-fw-open.yml`
```
- hosts: ws
tasks:
- name: Open RDP port
win_firewall_rule:
name: Open RDP port
localport: 3389
action: allow
direction: in
protocol: tcp
state: present
enabled: yes
```
`ansible-playbook /etc/ansible/win-fw-open.yml`
### win_group
`nano /etc/ansible/win-creat-group.yml`
```
- hosts: ws
tasks:
- name: Create a new group
win_group:
name: deploy
description: Deploy Group
state: present
```
`ansible-playbook /etc/ansible/win-creat-group.yml`
### win_group_membership
`nano /etc/ansible/add-user-to-group.yml`
```
- hosts: ws
tasks:
- name: Add a local and domain user to a local group
win_group_membership:
name: deploy
members:
- WinRM-Writer
state: present
```
`ansible-playbook /etc/ansible/add-user-to-group.yml`
### win_user
`nano /etc/ansible/creat-win-user.yml`
```
- hosts: ws
tasks:
- name: Creat user
win_user:
name: test
password: 123098
state: present
groups:
- deploy
```
`ansible-playbook /etc/ansible/creat-win-user.yml`
`nano /etc/ansible/delete-win-user.yml`
```
- hosts: ws
tasks:
- name: Delete user
ansible.windows.win_user:
name: test
state: absent
```
`ansible-playbook /etc/ansible/delete-win-user.yml`
### win_feature
`nano /etc/ansible/install-feature.yml`
```
- hosts: ws
tasks:
- name: Install Windows Feature
win_feature:
name: SNMP-Service
state: present
```
`ansible-playbook /etc/ansible/install-feature.yml`
### win_reboot
`nano /etc/ansible/win-reboot.yml`
```
- hosts: ws
tasks:
- name: Reboot a slow machine that might have lots of updates to apply
win_reboot:
reboot_timeout: 3600
```
`ansible-playbook /etc/ansible/win-reboot.yml`
### win_find
`nano /etc/ansible/win-ls.yml`
```
- hosts: ws
tasks:
- name: Find files in multiple paths
ansible.windows.win_find:
paths:
- D:\Install\OpenSource
patterns: ['*.rar','*.zip','*.msi']
` Файл созданный менее 7 дней назад
age: -7d
` Размер файла больше 10MB
size: 10485760
` Рекурсивный поиск (в дочерних директориях)
recurse: true
register: command_output
- name: Output
debug:
var: command_output
```
`ansible-playbook /etc/ansible/win-ls.yml`
### win_uri
`nano /etc/ansible/rest-get.yml`
```
- hosts: ws
tasks:
- name: REST GET request to endpoint github
ansible.windows.win_uri:
url: https://api.github.com/repos/Lifailon/pSyslog/releases/latest
register: http_output
- name: Output
debug:
var: http_output
```
`ansible-playbook /etc/ansible/rest-get.yml`
### win_updates
`nano /etc/ansible/win-update.yml`
```
- hosts: ws
tasks:
- name: Install only particular updates based on the KB numbers
ansible.windows.win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
- UpdateRollups
- Drivers
` Фильтрация
` accept_list:
` - KB2267602
` Поиск обновлений
` state: searched
` Загрузить обновления
` state: downloaded
` Установить обновления
state: installed
log_path: C:\Ansible-Windows-Upadte-Log.txt
reboot: false
register: wu_output
- name: Output
debug:
var: wu_output
```
`ansible-playbook /etc/ansible/win-update.yml`
### win_chocolatey
https://chocolatey.org/install \
https://community.chocolatey.org/api/v2/package/chocolatey \
https://docs.chocolatey.org/en-us/guides/organizations/organizational-deployment-guide
```
- name: Ensure Chocolatey installed from internal repo
win_chocolatey:
name: chocolatey
state: present
# source: URL-адрес внутреннего репозитория
source: https://community.chocolatey.org/api/v2/ChocolateyInstall.ps1
```
# GigaChat
### 1. Установка сертификатов:
`Invoke-WebRequest "https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt" -OutFile "$home\Downloads\russian_trusted_root_ca.cer"` скачать сертификат минцифры \
`Invoke-WebRequest "https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt" -OutFile "$home\Downloads\russian_trusted_sub_ca.cer"` \
`Import-Certificate -FilePath "$home\Downloads\russian_trusted_root_ca.cer" -CertStoreLocation "Cert:\CurrentUser\Root"` установить сертификат минцифры \
`Import-Certificate -FilePath "$home\Downloads\russian_trusted_sub_ca.cer" -CertStoreLocation "Cert:\CurrentUser\CA"`
### 2. Авторизация по Sber ID и генерация новых авторизационных данных для получения токена: https://developers.sber.ru/studio (время жизни 30 минут)
### 3. Формирование авторизационных данных в формате Base64 из Client ID и Client Secret:
```PowerShell
$Client_ID = "7e6d2f9f-825e-49b7-98f4-62fbb7506427" # [System.Guid]::Parse("7e6d2f9f-825e-49b7-98f4-62fbb7506427")
$Client_Secret = "c35113ee-6757-47ba-9853-ea1d0d9db1ef" # [System.Guid]::Parse("c35113ee-6757-47ba-9853-ea1d0d9db1ef")
$Client_Join = $Client_ID+":"+$Client_Secret # объединяем два UUID в одну строку, разделяя их символом ':'
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Client_Join) # преобразуем строку в массив байт
$Cred_Base64 = [Convert]::ToBase64String($Bytes) # кодируем байты в строку Base64
```
### 4. Получение токена:
`$Cred_Base64 = "N2U2ZDJmOWYtODI1ZS00OWI3LTk4ZjQtNjJmYmI3NTA2NDI3OmIyYzgwZmZmLTEzOGUtNDg1Mi05MjgwLWE2MGI4NTc0YTM2MQ=="` \
`$UUID = [System.Guid]::NewGuid()` генерируем UUID для журналирования входящих вызовов и разбора инцидентов
```PowerShell
$url = "https://ngw.devices.sberbank.ru:9443/api/v2/oauth"
$headers = @{
"Authorization" = "Basic $Cred_Base64"
"RqUID" = "$UUID"
"Content-Type" = "application/x-www-form-urlencoded"
}
$body = @{
scope = "GIGACHAT_API_PERS"
}
$GIGA_TOKEN = $(Invoke-RestMethod -Uri $url -Method POST -Headers $headers -Body $body).access_token
```
### 5. Параметры:
```PowerShell
[string]$content = "Посчитай сумму чисел: 22+33"
[string]$role = "user" # роль автора сообщения (user/assistant/system)
[float]$temperature = 0.7 # температура выборки в диапазоне от 0 до 2. Чем выше значение, тем более случайным будет ответ модели.
[float]$top_p = 0.1 # используется как альтернатива temperature и изменяется в диапазоне от 0 до 1. Задает вероятностную массу токенов, которые должна учитывать модель. Так, если передать значение 0.1, модель будет учитывать только токены, чья вероятностная масса входит в верхние 10%.
[int64]$n = 1 # количество вариантов ответов (1..4), которые нужно сгенерировать для каждого входного сообщения
[int64]$max_tokens = 512 # максимальное количество токенов, которые будут использованы для создания ответов
[boolean]$stream = $false # передавать сообщения по частям в потоке
```
### 6. Составление запросов:
```PowerShell
$url = "https://gigachat.devices.sberbank.ru/api/v1/chat/completions"
$headers = @{
"Authorization" = "Bearer $GIGA_TOKEN"
"Content-Type" = "application/json"
}
$(Invoke-RestMethod -Uri "https://gigachat.devices.sberbank.ru/api/v1/models" -Headers $headers).data # список доступных моделей
$body = @{
model = "GigaChat:latest"
messages = @(
@{
role = $role
content = $content
}
)
temperature = $temperature
n = $n
max_tokens = $max_tokens
stream = $stream
} | ConvertTo-Json
$Request = Invoke-RestMethod -Method POST -Uri $url -Headers $headers -Body $body
$Request.choices.message.content
```
## Curl
### Установка сертификатов в Ubuntu:
`wget https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt` \
`wget https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt` \
`mkdir /usr/local/share/ca-certificates/russian_trusted` \
`cp russian_trusted_root_ca_pem.crt russian_trusted_sub_ca_pem.crt /usr/local/share/ca-certificates/russian_trusted` \
`update-ca-certificates -v` \
`wget -qS --spider --max-redirect=0 https://www.sberbank.ru`
### Получение токена:
```Bash
Cred_Base64="N2U2ZDJmOWYtODI1ZS00OWI3LTk4ZjQtNjJmYmI3NTA2NDI3OmIyYzgwZmZmLTEzOGUtNDg1Mi05MjgwLWE2MGI4NTc0YTM2MQ=="
UUID=$(uuidgen)
GIGA_TOKEN=$(curl -s --location --request POST "https://ngw.devices.sberbank.ru:9443/api/v2/oauth" \
--header "Authorization: Basic $Cred_Base64" \
--header "RqUID: $UUID" \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode 'scope=GIGACHAT_API_PERS' | jq -r .access_token)
```
`curl -s --location "https://gigachat.devices.sberbank.ru/api/v1/models" --header "Authorization: Bearer $GIGA_TOKEN" | jq .` для проверки
### Составление запроса:
```Bash
request=$(curl -s https://gigachat.devices.sberbank.ru/api/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $GIGA_TOKEN" \
-d '{
"model": "GigaChat:latest",
"messages": [
{
"role": "user",
"content": "Когда уже ИИ захватит этот мир?"
}
],
"temperature": 0.7
}')
echo $request | jq -r .choices[].message.content
```
# YandexGPT
## Получить OAuth-Token:
https://cloud.yandex.ru/ru/docs/iam/operations/iam-token/create время жизни IAM-токена не больше 12 часов \
`yandexPassportOauthToken="y0_AgAAAAAGaLFLAATuwQAAAAD3xtRLQE4hvlazQ5euKO43XXXXXXXXXXX"` для bash \
`$yandexPassportOauthToken = "y0_AgAAAAAGaLFLAATuwQAAAAD3xtRLQE4hvlazQ5euKO43XXXXXXXXXXX"` для PowerShell
## Обменять OAuth-Token на IAM-Token:
`IAM_TOKEN=$(curl -s -d "{\"yandexPassportOauthToken\":\"$yandexPassportOauthToken\"}" "https://iam.api.cloud.yandex.net/iam/v1/tokens" | jq -r .iamToken)` \
`$IAM_TOKEN = $(Invoke-RestMethod -Method POST -Uri "https://iam.api.cloud.yandex.net/iam/v1/tokens" -Body $(@{yandexPassportOauthToken = "$yandexPassportOauthToken"} | ConvertTo-Json -Compress)).iamToken`
## Получить FOLDER_ID:
```Bash
CLOUD_ID=$(curl -s -H "Authorization: Bearer $IAM_TOKEN" https://resource-manager.api.cloud.yandex.net/resource-manager/v1/clouds | jq -r .clouds[].id) # получить cloud id
curl -s --request GET -H "Authorization: Bearer $IAM_TOKEN" https://resource-manager.api.cloud.yandex.net/resource-manager/v1/folders -d "{\"cloudId\": \"$CLOUD_ID\"}" # получить список директорий в облаке
curl -s --request POST -H "Authorization: Bearer $IAM_TOKEN" https://resource-manager.api.cloud.yandex.net/resource-manager/v1/folders -d "{\"cloudId\": \"$CLOUD_ID\", \"name\": \"test\"}" # создать директорию в облаке
FOLDER_ID=$(curl -s --request GET -H "Authorization: Bearer $IAM_TOKEN" https://resource-manager.api.cloud.yandex.net/resource-manager/v1/folders -d '{"cloudId": "b1gf9n6heihqj0pt5piu"}' | jq -r '.folders[] | select(.name == "test") | .id') # забрать id директории
```
```PowerShell
$CLOUD_ID = $(Invoke-RestMethod -Method Get -Uri "https://resource-manager.api.cloud.yandex.net/resource-manager/v1/clouds" -Headers @{"Authorization"="Bearer $IAM_TOKEN"; "Content-Type"="application/json"}).clouds.id
$FOLDER_ID = $(Invoke-RestMethod -Method Get -Uri "https://resource-manager.api.cloud.yandex.net/resource-manager/v1/folders" -Headers @{"Authorization"="Bearer $IAM_TOKEN"; "Content-Type"="application/json"} -Body (@{"cloudId"= $CLOUD_ID} | ConvertTo-Json)).folders | Where-Object name -eq test | Select-Object -ExpandProperty id
```
### Составление запроса:
```Bash
model="gpt://$FOLDER_ID/yandexgpt/latest" # https://cloud.yandex.ru/ru/docs/yandexgpt/concepts/models
body=$(cat <