diff --git a/API/Get-GoogleTranslate.psm1 b/API/Get-GoogleTranslate.psm1
new file mode 100644
index 0000000..517e077
--- /dev/null
+++ b/API/Get-GoogleTranslate.psm1
@@ -0,0 +1,18 @@
+function Get-Translate ($data) {
+ $Key = "KEY" # Get https://cloud.google.com/translate/docs/reference/rest
+ $url = "https://translation.googleapis.com/language/translate/v2?key=$Key"
+ $body = @{
+ q = $data
+ target = "ru"
+ source = "en"
+ } | ConvertTo-Json
+ try {
+ $response = Invoke-RestMethod -Uri $url -Method POST -ContentType "application/json" -Body $body
+ $translation = $response.data.translations[0].translatedText
+ return $translation
+ } catch {
+ Write-Output "Error: $($_.Exception.Message)"
+ }
+}
+
+# Get-Translate $("What is your name")
\ No newline at end of file
diff --git a/API/PerformanceTo-InfluxDB.ps1 b/API/PerformanceTo-InfluxDB.ps1
new file mode 100644
index 0000000..6ffa3b0
--- /dev/null
+++ b/API/PerformanceTo-InfluxDB.ps1
@@ -0,0 +1,27 @@
+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
+ $timestamp = ([string]$unixtime -replace "\..+") + "000000000"
+ [double]$value = (Get-Counter $performance).CounterSamples.CookedValue.ToString("0.00").replace(",",".")
+ 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
+}
\ No newline at end of file
diff --git a/API/PingTo-InfluxDB.ps1 b/API/PingTo-InfluxDB.ps1
new file mode 100644
index 0000000..f352e13
--- /dev/null
+++ b/API/PingTo-InfluxDB.ps1
@@ -0,0 +1,10 @@
+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
+}
\ No newline at end of file
diff --git a/API/Pode-WinMan.ps1 b/API/Pode-WinMan.ps1
new file mode 100644
index 0000000..fc9806d
--- /dev/null
+++ b/API/Pode-WinMan.ps1
@@ -0,0 +1,52 @@
+Start-PodeServer {
+ Add-PodeEndpoint -Address localhost -Port "8080" -Protocol "HTTP"
+ ### Get info endpoints
+ Add-PodeRoute -Path "/" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value @{
+ "service"="/api/service";
+ "process"="/api/process"
+ }
+ }
+ ### GET
+ Add-PodeRoute -Path "/api/service" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value $(
+ Get-Service | Select-Object Name,@{
+ Name="Status"; Expression={[string]$_.Status}
+ },@{
+ Name="StartType"; Expression={[string]$_.StartType}
+ } | ConvertTo-Json
+ )
+ }
+ Add-PodeRoute -Path "/api/process" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value $(
+ Get-Process | Sort-Object -Descending CPU | Select-Object -First 15 ProcessName,
+ @{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+ @{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+ @{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}}
+ )
+ }
+ Add-PodeRoute -Path "/api/process-html" -Method "GET" -ScriptBlock {
+ Write-PodeHtmlResponse -Value (
+ Get-Process | Sort-Object -Descending CPU | Select-Object -First 15 ProcessName,
+ @{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+ @{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+ @{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}} # Auto ConvertTo-Html
+ )
+ }
+ ### POST
+ Add-PodeRoute -Path "/api/service" -Method "POST" -ScriptBlock {
+ # https://pode.readthedocs.io/en/latest/Tutorials/WebEvent/
+ # $WebEvent | Out-Default
+ $Value = $WebEvent.Data["ServiceName"]
+ $Status = (Get-Service -Name $Value).Status
+ Write-PodeJsonResponse -Value @{
+ "Name"="$Value";
+ "Status"="$Status";
+ }
+ }
+}
+
+# irm http://localhost:8080/api/service -Method Get
+# irm http://localhost:8080/api/process -Method Get
+# irm http://localhost:8080/api/process-html -Method Get
+# irm http://localhost:8080/api/service -Method Post -Body @{"ServiceName" = "AnyDesk"}
\ No newline at end of file
diff --git a/API/Zabbix-API-Last-Uptime-All-Hosts.ps1 b/API/Zabbix-API-Last-Uptime-All-Hosts.ps1
new file mode 100644
index 0000000..538879e
--- /dev/null
+++ b/API/Zabbix-API-Last-Uptime-All-Hosts.ps1
@@ -0,0 +1,92 @@
+$ip = "192.168.3.102"
+$url = "http://$ip/zabbix/api_jsonrpc.php"
+$token = "914ee100f4e8c4b68a70eab2a0a1fb153cfcd4905421d0ffacb82c20a57aa50e"
+
+function ConvertFrom-UnixTime {
+ param (
+ $intime
+ )
+ $EpochTime = [DateTime]"1/1/1970"
+ $TimeZone = Get-TimeZone
+ $UTCTime = $EpochTime.AddSeconds($intime)
+ $UTCTime.AddMinutes($TimeZone.BaseUtcOffset.TotalMinutes)
+}
+
+function ConvertTo-TimeSpan {
+ param (
+ $insec
+ )
+ $TimeSpan = [TimeSpan]::fromseconds($insec)
+ "{0:dd' day 'hh\:mm\:ss}" -f $TimeSpan
+}
+
+### Получить список всех хостов (имя и id)
+$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
+
+### Получить id элемента данных по наименованию ключа для каждого хоста
+$Collections = New-Object System.Collections.Generic.List[System.Object]
+foreach ($h in $hosts) {
+ $data = @{
+ "jsonrpc"="2.0";
+ "method"="item.get";
+ "params"=@{
+ "hostids"=@($h.hostid);
+ };
+ "auth"=$token;
+ "id"=1;
+ }
+ $items = (Invoke-RestMethod -Method POST -Uri $url -Body ($data | ConvertTo-Json) -ContentType "application/json").Result
+ $items_id = ($items | Where-Object key_ -match system.uptime).itemid
+ if ($items_id -ne $null) {
+ $Collections.Add([PSCustomObject]@{
+ host = $h.host;
+ hostid = $h.hostid;
+ item_id_uptime = $items_id
+ })
+ }
+}
+
+### Получить всю историю элемента данных по его id для каждого хоста
+$Collections_output = New-Object System.Collections.Generic.List[System.Object]
+foreach ($c in $Collections) {
+ $data = @{
+ "jsonrpc"="2.0";
+ "method"="history.get";
+ "params"=@{
+ "hostids"=$c.hostid;
+ "itemids"=$c.item_id_uptime;
+ };
+ "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
+ $UpTime = ConvertTo-TimeSpan $sec[-1]
+
+ ### Convert From Unix Time
+ $time = $items_data_uptime.clock
+ $GetDataTime = ConvertFrom-UnixTime $time[-1]
+
+ $Collections_output.Add([PSCustomObject]@{
+ host = $c.host;
+ hostid = $c.hostid;
+ item_id_uptime = $c.item_id_uptime;
+ GetDataTime = $GetDataTime
+ UpTime = $UpTime
+ })
+}
+$Collections_output | Format-Table
\ No newline at end of file
diff --git a/README.md b/README.md
index e5b8a39..a86c304 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
- [Object](#object)
- [Regex](#regex)
@@ -31,8 +31,9 @@
- [TrueNAS](#truenas)
- [Veeam](#veeam)
- [REST API](#rest-api)
-- [IE](#ie)
+- [Pode](#pode)
- [Selenium](#selenium)
+- [IE](#ie)
- [COM](#com)
- [dotNET](#dotnet)
- [Console API](#console-api)
@@ -391,6 +392,7 @@ foreach ($p in $gp) {
### Специальные символы
`\d` число от 0 до 9 (20-07-2022 эквивалент: "\d\d-\d\d-\d\d\d\d") \
+`\D` обозначает любой символ, кроме цифры. Удаления всех символов, кроме цифр: [int]$("123 test" -replace "\D","") \
`\w` буква от "a" до "z" и от "A" до "Z" или число от 0 до 9 \
`\s` пробел, эквивалент: " " \
`\n` новая строка \
@@ -2430,6 +2432,61 @@ ConvertTo-Json -Compress -InputObject $payload
```
`Send-Telegram -Text Test`
+# Pode
+```
+Start-PodeServer {
+ Add-PodeEndpoint -Address localhost -Port "8080" -Protocol "HTTP"
+ ### Get info endpoints
+ Add-PodeRoute -Path "/" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value @{
+ "service"="/api/service";
+ "process"="/api/process"
+ }
+ }
+ ### GET
+ Add-PodeRoute -Path "/api/service" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value $(
+ Get-Service | Select-Object Name,@{
+ Name="Status"; Expression={[string]$_.Status}
+ },@{
+ Name="StartType"; Expression={[string]$_.StartType}
+ } | ConvertTo-Json
+ )
+ }
+ Add-PodeRoute -Path "/api/process" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value $(
+ Get-Process | Sort-Object -Descending CPU | Select-Object -First 15 ProcessName,
+ @{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+ @{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+ @{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}}
+ )
+ }
+ Add-PodeRoute -Path "/api/process-html" -Method "GET" -ScriptBlock {
+ Write-PodeHtmlResponse -Value (
+ Get-Process | Sort-Object -Descending CPU | Select-Object -First 15 ProcessName,
+ @{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+ @{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+ @{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}} # Auto ConvertTo-Html
+ )
+ }
+ ### POST
+ Add-PodeRoute -Path "/api/service" -Method "POST" -ScriptBlock {
+ # https://pode.readthedocs.io/en/latest/Tutorials/WebEvent/
+ # $WebEvent | Out-Default
+ $Value = $WebEvent.Data["ServiceName"]
+ $Status = (Get-Service -Name $Value).Status
+ Write-PodeJsonResponse -Value @{
+ "Name"="$Value";
+ "Status"="$Status";
+ }
+ }
+}
+```
+`irm http://localhost:8080/api/service -Method Get` \
+`irm http://localhost:8080/api/process -Method Get` \
+`http://localhost:8080/api/process-html` использовать браузер \
+`irm http://localhost:8080/api/service -Method Post -Body @{"ServiceName" = "AnyDesk"}`
+
# Selenium
`.\nuget.exe install Selenium.WebDriver` \
diff --git a/Scripts/Export-Excel.psm1 b/Scripts/Export-Excel.psm1
new file mode 100644
index 0000000..814a1b2
Binary files /dev/null and b/Scripts/Export-Excel.psm1 differ
diff --git a/Scripts/Get-ARP.psm1 b/Scripts/Get-ARP.psm1
new file mode 100644
index 0000000..f14cb49
--- /dev/null
+++ b/Scripts/Get-ARP.psm1
@@ -0,0 +1,52 @@
+function Get-ARP {
+<#
+.SYNOPSIS
+Module using arp.exe for created object powershell and search mac-address
+For proxy use Invoke-Command via WinRM
+.DESCRIPTION
+Example:
+Get-MACProxy # default localhost
+Get-MACProxy -proxy dc-01 # remote get arp table
+Get-MACProxy -proxy dc-01 -search server-01 # search mac-address server on proxy-server
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$proxy,
+$search
+)
+if (!$proxy) {
+$arp = arp -a
+}
+if ($proxy) {
+$arp = icm $proxy {arp -a}
+}
+$mac = $arp[3..260]
+$mac = $mac -replace "^\s\s"
+$mac = $mac -replace "\s{1,50}"," "
+$mac_coll = New-Object System.Collections.Generic.List[System.Object]
+foreach ($m in $mac) {
+$smac = $m -split " "
+$mac_coll.Add([PSCustomObject]@{
+IP = $smac[0];
+MAC = $smac[1];
+Type = $smac[2]
+})
+}
+if ($search) {
+if ($search -NotMatch "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") {
+#$ns = nslookup $search
+#$ns = $ns[-2]
+#$global:ns = $ns -replace "Address:\s{1,10}"
+$rdns = Resolve-DnsName $search -ErrorAction Ignore
+$ns = $rdns.IPAddress
+if ($ns -eq $null) {
+return
+}
+} else {
+$ns = $search
+}
+$mac_coll = $mac_coll | ? ip -Match $ns
+}
+$mac_coll
+}
\ No newline at end of file
diff --git a/Scripts/Get-Broker.psm1 b/Scripts/Get-Broker.psm1
new file mode 100644
index 0000000..4f975bc
--- /dev/null
+++ b/Scripts/Get-Broker.psm1
@@ -0,0 +1,50 @@
+function Get-Broker {
+<#
+.SYNOPSIS
+Add-on for module RemoteDesktop
+Features:
+Remote shadow connection to user via rdp
+Disconnect user
+Collection list and software
+Host list and roles
+.DESCRIPTION
+Example:
+Get-Broker localhost -r # remote shadow connection to user via rdp
+Get-Broker localhost -d # disconnect user
+Get-Broker localhost -c # collection list and software
+Get-Broker localhost -h # host list and roles
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$broker="localhost",
+[switch]$r,
+[switch]$d,
+[switch]$c,
+[switch]$h
+)
+if ($c) {
+$Coll = Get-RDRemoteDesktop -ConnectionBroker $broker | Out-GridView -title "Broker-Connect" -PassThru
+$CollName = $Coll.CollectionName
+}
+if ($CollName) {
+Get-RDAvailableApp -ConnectionBroker $broker -CollectionName $CollName | Out-GridView -title "Software $CollName"
+}
+if ($h) {
+Get-RDServer -ConnectionBroker $broker | Out-GridView -title "Broker-Connect"
+}
+if (($r) -or ($d)) {
+$out = Get-RDUserSession -ConnectionBroker $broker | select hostserver, UserName, SessionState, CreateTime, DisconnectTime,
+unifiedsessionid | Out-GridView -title "Broker-Connect" -PassThru | select hostserver, unifiedsessionid
+}
+if ($out) {
+$srv = $out.HostServer
+$id = $out.UnifiedSessionId
+if ($r) {
+mstsc /v:"$srv" /shadow:"$id" /control /noconsentprompt
+}
+if ($d) {
+Disconnect-RDUser -HostServer $srv -UnifiedSessionID $id # -Force
+}
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-EventTS.psm1 b/Scripts/Get-EventTS.psm1
new file mode 100644
index 0000000..3da7c21
--- /dev/null
+++ b/Scripts/Get-EventTS.psm1
@@ -0,0 +1,63 @@
+function Get-EventTS {
+<#
+.SYNOPSIS
+Parsing remote and local Windows Events Terminal Services
+.DESCRIPTION
+Example:
+Get-EventTS localhost -connect # User authentication succeeded
+Get-EventTS localhost -logon # Shell start notification received
+Get-EventTS localhost -logoff # Session logoff succeeded
+Get-EventTS localhost -disconnect # Session has been disconnected
+Get-EventTS localhost -reconnect # Session reconnection succeeded
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost",
+[switch]$connect,
+[switch]$logon,
+[switch]$logoff,
+[switch]$disconnect,
+[switch]$reconnect
+)
+if ($connect) {
+$RDPAuths = Get-WinEvent -ComputerName $srv -LogName "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational" `
+-FilterXPath ''
+[xml[]]$xml = $RDPAuths | Foreach {$_.ToXml()}
+$EventData = Foreach ($event in $xml.Event) {
+New-Object PSObject -Property @{
+"Connection Time" = (Get-Date ($event.System.TimeCreated.SystemTime) -Format 'yyyy-MM-dd hh:mm K')
+"User Name" = $event.UserData.EventXML.Param1
+"User Address" = $event.UserData.EventXML.Param3
+"Event ID" = $event.System.EventID
+}}
+$EventData | Out-Gridview -Title "TS-Remote-Connection-Manager to server $srv"
+}
+
+if (!($connect)) {
+if ($logon) {
+$FilterXPath = ''
+}
+if ($logoff) {
+$FilterXPath = ''
+}
+if ($disconnect) {
+$FilterXPath = ''
+}
+if ($reconnect) {
+$FilterXPath = ''
+}
+$RDPAuths = Get-WinEvent -ComputerName $srv -LogName "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" `
+-FilterXPath $FilterXPath
+[xml[]]$xml = $RDPAuths | Foreach {$_.ToXml()}
+$EventData = Foreach ($event in $xml.Event) {
+New-Object PSObject -Property @{
+"Connection Time" = (Get-Date ($event.System.TimeCreated.SystemTime) -Format 'yyyy-MM-dd hh:mm K')
+"User Name" = $event.UserData.EventXML.User
+"User ID" = $event.UserData.EventXML.SessionID
+"User Address" = $event.UserData.EventXML.Address
+"Event ID" = $event.System.EventID
+}}
+$EventData | Out-Gridview -Title "TS-Local-Session-Manager to server $srv"
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-Netstat.psm1 b/Scripts/Get-Netstat.psm1
new file mode 100644
index 0000000..fc4d365
--- /dev/null
+++ b/Scripts/Get-Netstat.psm1
@@ -0,0 +1,30 @@
+function Get-Netstat {
+<#
+.SYNOPSIS
+Remote and local view network tcp connections statistics and his used process
+Using Get-NetTCPConnection, ps, nslookup and Invoke-Command via WinRM
+.DESCRIPTION
+Example:
+Get-Netstat localhost # default
+Get-Netstat server-01 # remote host
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost"
+)
+if ($srv -like "localhost") {
+Get-NetTCPConnection -State Established,Listen | sort -Descending State | select CreationTime,LocalAddress,LocalPort,RemotePort,
+@{name="RemoteHostName";expression={((nslookup $_.RemoteAddress)[3]) -replace ".+:\s+"}},RemoteAddress,
+State,@{name="ProcessName";expression={(ps -Id $_.OwningProcess).ProcessName}},
+@{name="ProcessPath";expression={(ps -Id $_.OwningProcess).Path}} | Out-GridView -Title "Local netstat"
+}
+else {
+icm $srv {Get-NetTCPConnection -State Established,Listen | sort -Descending State | select CreationTime,LocalAddress,LocalPort,
+RemotePort,RemoteAddress,
+State,@{name="ProcessName";expression={(ps -Id $_.OwningProcess).ProcessName}},
+@{name="ProcessPath";expression={(ps -Id $_.OwningProcess).Path}}} | select CreationTime,LocalAddress,LocalPort,RemotePort,
+@{name="RemoteHostName";expression={((nslookup $_.RemoteAddress)[3]) -replace ".+:\s+"}},
+RemoteAddress,State,ProcessName,ProcessPath | Out-GridView -Title "Remote netstat to server: $srv"
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-RemoteDNS.psm1 b/Scripts/Get-RemoteDNS.psm1
new file mode 100644
index 0000000..d81bb10
--- /dev/null
+++ b/Scripts/Get-RemoteDNS.psm1
@@ -0,0 +1,42 @@
+function Get-RemoteDNS {
+<#
+.SYNOPSIS
+Module for remote view zones DNS, as well view and remove records
+Using module DNS Server (from RSAT set) via Invoke-Command (module installation is not required)
+.DESCRIPTION
+Example:
+Get-RemoteDNS dc-01
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv
+)
+if (!$srv) {
+Write-Host (Get-Help Get-RemoteDNS).DESCRIPTION.Text -ForegroundColor Cyan
+return
+}
+$zone = icm $srv {Get-DnsServerZone} | select ZoneName,ZoneType,DynamicUpdate,ReplicationScope,SecureSecondaries,
+DirectoryPartitionName | Out-GridView -Title "DNS Server: $srv" PassThru
+$zone_name = $zone.ZoneName
+if ($zone_name -ne $null) {
+$A = icm $srv {
+Get-DnsServerResourceRecord -ZoneName $using:zone_name | sort RecordType | select RecordType,HostName, @{
+Label="IPAddress"; Expression={$_.RecordData.IPv4Address.IPAddressToString}},TimeToLive,Timestamp
+} | select RecordType,HostName,IPAddress,TimeToLive,Timestamp | Out-GridView -Title "DNS Server: $srv | Zone: $zone_name" PassThru
+}
+if ($A -ne $null) {
+$RT = $A.RecordType
+$HN = $A.HostName
+$wshell = New-Object -ComObject Wscript.Shell
+$output = $wshell.Popup("Romove record $HN (type: $RT)",0,"Select",4)
+if ($output -eq 6) {
+icm $srv {
+Remove-DnsServerResourceRecord -ZoneName $using:zone_name -RRType $using:RT -Name $using:HN Force
+}
+}
+if ($output -eq 7) {
+Write-Host "Canceled"
+}
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-Size.psm1 b/Scripts/Get-Size.psm1
new file mode 100644
index 0000000..9d3bbb8
--- /dev/null
+++ b/Scripts/Get-Size.psm1
@@ -0,0 +1,33 @@
+function Get-Size {
+<#
+.SYNOPSIS
+Remote and local check use and all memory or space logical disk
+For remote use applyed Invoke-Command via WinRM for memory and WMI for logical disk
+.DESCRIPTION
+Example:
+Get-Size -disk localhost # default
+Get-Size -memory localhost
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost",
+[switch]$memory,
+[switch]$disk
+)
+if ($memory) {
+if ($srv -like "localhost") {
+$mem = Get-ComputerInfo
+} else {
+$mem = Invoke-Command -ComputerName $srv -ScriptBlock {Get-ComputerInfo}
+}
+$mem | select @{
+Label="Size"; Expression={[string]($_.CsPhyicallyInstalledMemory/1mb)+" Gb"}},
+@{Label="Free"; Expression={[string]([int]($_.OsFreePhysicalMemory/1kb))+" Mb"}}
+} else {
+gwmi Win32_logicalDisk -ComputerName $srv | select @{Label="Volume"; Expression={$_.DeviceID}},
+@{Label="Size"; Expression={[string]([int]($_.Size/1Gb))+" Gb"}},
+@{Label="Free"; Expression={[string]([int]($_.FreeSpace/1Gb))+" Gb"}},
+@{Label="%Free"; Expression={[string]([int]($_.FreeSpace/$_.Size*100))+" %"}}
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-Soft.psm1 b/Scripts/Get-Soft.psm1
new file mode 100644
index 0000000..b98afc3
--- /dev/null
+++ b/Scripts/Get-Soft.psm1
@@ -0,0 +1,74 @@
+function Get-Soft {
+<#
+.SYNOPSIS
+Remote and local view and delete software via WMI or Get-Package
+.DESCRIPTION
+Example:
+Get-Soft localhost # default (or remote host)
+Get-Soft localhost -wmi # use delete via WMI
+Get-Soft localhost -package # use delete via Get-Package
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost",
+[switch]$wmi,
+[switch]$package
+)
+if ($wmi) {
+$soft_wmi = gwmi Win32_Product -ComputerName $srv | select Name,Version,Vendor,
+InstallDate,InstallLocation,InstallSource | sort -Descending InstallDate |
+Out-Gridview -Title "Software to server $srv" -PassThru
+$soft_wmi_uninstall = $soft_wmi.Name
+if ($soft_wmi_uninstall -ne $null) {
+$wshell = New-Object -ComObject Wscript.Shell
+$output = $wshell.Popup("Delete $soft_wmi_uninstall to server $srv ?",0,"Select action",4)
+} else {
+Write-Host Canceled
+break
+}
+if ($output -eq "7") {
+Write-Host Canceled
+break
+}
+if ($output -eq "6") {
+$uninstall = (gwmi Win32_Product -ComputerName $srv -Filter "Name = '$soft_wmi_uninstall'").Uninstall()
+$outcode = $uninstall.ReturnValue
+if ($outcode -eq 0) {
+Write-Host -ForegroundColor Green "Successfully"
+} else {
+Write-Host -ForegroundColor Red "Error: $outcode"
+}
+}
+}
+if ($package) {
+if ($srv -like "localhost") {
+$soft_pack = Get-Package -ProviderName msi,Programs | Out-Gridview -Title "Software to server $srv" -PassThru
+} else {
+$soft_pack = icm $srv {Get-Package} | ? ProviderName -match "(Programs)|(msi)" | Out-Gridview -Title "Software to server $srv" -PassThru
+}
+if ($soft_pack -ne $null) {
+$soft_name = $soft_pack.Name
+$wshell = New-Object -ComObject Wscript.Shell
+$output = $wshell.Popup("Delete $soft_name to server $srv ?",0,"Select action",4)
+} else {
+Write-Host Canceled
+break
+}
+if ($output -eq "7") {
+Write-Host Canceled
+break
+}
+if ($output -eq "6") {
+if ($srv -like "localhost") {
+Get-Package -Name "$soft_name" | Uninstall-Package -Force -ForceBootstrap
+} else {
+$session = New-PSSession $srv
+icm -Session $session {
+Get-Package -Name "$using:soft_name" | Uninstall-Package -Force -ForceBootstrap
+}
+Remove-PSSession $session
+}
+}
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-Update.psm1 b/Scripts/Get-Update.psm1
new file mode 100644
index 0000000..35c6e27
--- /dev/null
+++ b/Scripts/Get-Update.psm1
@@ -0,0 +1,50 @@
+function Get-Update {
+<#
+.SYNOPSIS
+Remote and local view and delete updates packages
+Using WMI, dism Online and Invoke-Command via WinRM
+.DESCRIPTION
+Example:
+Get-Update localhost # windows updates list (WMI) default
+Get-Update localhost | Out-GridView
+Get-Update localhost -delete # DISM packages list for delete updates
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost",
+[switch]$delete
+)
+if ($delete){
+if ($srv -like "localhost") {
+$dismName = dism /Online /Get-Packages /format:table |
+Out-Gridview -Title "DISM $Text_Packages $Text_ToServer $srv" PassThru
+if ($dismName -ne $null) {
+$dismNamePars = $dismName -replace "\|.+"
+$dismNamePars = $dismNamePars -replace "\s"
+$wshell = New-Object -ComObject Wscript.Shell
+$output = $wshell.Popup("Delete Update $dismNamePars to server $srv ?",0,"Select action",4)
+if ($output -eq "6") {
+dism /Online /Remove-Package /PackageName:$dismNamePars /quiet /norestart
+}
+}
+} else {
+$session = New-PSSession $srv
+$dismName = icm -Session $session {dism /Online /Get-Packages /format:table} |
+Out-Gridview -Title "DISM $Text_Packages $Text_ToServer $srv" PassThru
+if ($dismName -ne $null) {
+$dismNamePars = $dismName -replace "\|.+"
+$dismNamePars = $dismNamePars -replace "\s"
+$wshell = New-Object -ComObject Wscript.Shell
+$output = $wshell.Popup("Delete Update $dismNamePars to server $srv ?",0,"Select action",4)
+if ($output -eq "6") {
+icm -Session $session {$dismNamePars = $using:dismNamePars}
+icm -Session $session {dism /Online /Remove-Package /PackageName:$dismNamePars /quiet /norestart}
+Remove-PSSession $session
+}
+}
+}
+} else {
+Get-WmiObject -Class Win32_QuickFixEngineering -ComputerName $srv
+}
+}
\ No newline at end of file
diff --git a/Scripts/Get-Uptime.psm1 b/Scripts/Get-Uptime.psm1
new file mode 100644
index 0000000..5a2d178
--- /dev/null
+++ b/Scripts/Get-Uptime.psm1
@@ -0,0 +1,29 @@
+function Get-Uptime {
+<#
+.SYNOPSIS
+Remote and local check uptime via WMI
+.DESCRIPTION
+Example:
+Get-Uptime localhost # default (or remote host)
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost"
+)
+if ($srv -like "localhost") {
+$boottime = Get-CimInstance Win32_OperatingSystem | select LastBootUpTime
+} else {
+$boottime = Get-CimInstance -ComputerName $srv Win32_OperatingSystem | select LastBootUpTime
+}
+$datetime = (Get-Date) - $boottime.LastBootUpTime
+$global:uptime = [string]$datetime.Days+" days "+[string]$datetime.Hours+" hours "+
+[string]$datetime.Minutes+" minutes"
+$LastTime = [string]$boottime.LastBootUpTime.DateTime
+$Collections = New-Object System.Collections.Generic.List[System.Object]
+$Collections.Add([PSCustomObject]@{
+Uptime = $uptime;
+BootTime = $LastTime
+})
+$Collections
+}
\ No newline at end of file
diff --git a/Scripts/Get-UserProcess.psm1 b/Scripts/Get-UserProcess.psm1
new file mode 100644
index 0000000..2b52067
--- /dev/null
+++ b/Scripts/Get-UserProcess.psm1
@@ -0,0 +1,44 @@
+function Get-UserProcess {
+<#
+.SYNOPSIS
+Remote and local view and stop processes
+Using Get-Process and Invoke-Command via WinRM
+.DESCRIPTION
+Example:
+Get-UserProcess localhost # default (Run as Administartor)
+Get-UserProcess localhost -stop # stop process force
+.LINK
+https://github.com/Lifailon
+#>
+Param (
+$srv="localhost",
+[switch]$stop
+)
+if ($srv -like "localhost") {
+$ps_out = ps -IncludeUserName | Sort-Object -Descending CPU | select ProcessName,Product,
+ProductVersion,UserName,
+@{Name="Processor Time sec"; Expression={[int]$_.CPU}},
+@{Name="Processor Time min"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+@{Name="Memory WS"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+@{Name="Memory PM"; Expression={[string]([int]($_.PM / 1024kb))+"MB"}},
+@{Name="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}},
+Path | Out-GridView -Title "Local user processes" -PassThru
+if ($stop -and $ps_out) {
+$ps_out | Stop-Process -Force
+}
+} else {
+$ps_out = icm $srv {ps -IncludeUserName} | Sort-Object -Descending CPU | select ProcessName,Product,
+ProductVersion,UserName,
+@{Name="Processor Time sec"; Expression={[int]$_.CPU}},
+@{Name="Processor Time min"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+@{Name="Memory WS"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+@{Name="Memory PM"; Expression={[string]([int]($_.PM / 1024kb))+"MB"}},
+@{Name="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}},
+Path | Out-GridView -Title "Remote user processes to server $srv" -PassThru
+if ($stop -and $ps_out) {
+$session = New-PSSession $srv
+icm -Session $session {Stop-Process -Name $using:ps_out.ProcessName -Force}
+Remove-PSSession $session
+}
+}
+}
\ No newline at end of file
diff --git a/Scripts/Import-Excel.psm1 b/Scripts/Import-Excel.psm1
new file mode 100644
index 0000000..f4af62a
Binary files /dev/null and b/Scripts/Import-Excel.psm1 differ
diff --git a/Scripts/Services-to-Excel.ps1 b/Scripts/Services-to-Excel.ps1
new file mode 100644
index 0000000..47df58b
Binary files /dev/null and b/Scripts/Services-to-Excel.ps1 differ
diff --git a/posh.txt b/posh.txt
index bcc797c..a062d20 100644
--- a/posh.txt
+++ b/posh.txt
@@ -31,8 +31,9 @@ PowerShell Commands
# TrueNAS
# Veeam
# REST API
-# IE
+# Pode
# Selenium
+# IE
# COM
# dotNET
# Console API
@@ -391,6 +392,7 @@ $ping = "ping"
### Специальные символы
\d # число от 0 до 9 (20-07-2022 эквивалент: "\d\d-\d\d-\d\d\d\d")
+\D # обозначает любой символ, кроме цифры. Удаления всех символов, кроме цифр: [int]$("123 test" -replace "\D","")
\w # буква от "a" до "z" и от "A" до "Z" или число от 0 до 9
\s # пробел, эквивалент: " "
\n # новая строка
@@ -2430,6 +2432,61 @@ ConvertTo-Json -Compress -InputObject $payload
Send-Telegram -Text Test
+# Pode
+
+Start-PodeServer {
+ Add-PodeEndpoint -Address localhost -Port "8080" -Protocol "HTTP"
+ ### Get info endpoints
+ Add-PodeRoute -Path "/" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value @{
+ "service"="/api/service";
+ "process"="/api/process"
+ }
+ }
+ ### GET
+ Add-PodeRoute -Path "/api/service" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value $(
+ Get-Service | Select-Object Name,@{
+ Name="Status"; Expression={[string]$_.Status}
+ },@{
+ Name="StartType"; Expression={[string]$_.StartType}
+ } | ConvertTo-Json
+ )
+ }
+ Add-PodeRoute -Path "/api/process" -Method "GET" -ScriptBlock {
+ Write-PodeJsonResponse -Value $(
+ Get-Process | Sort-Object -Descending CPU | Select-Object -First 15 ProcessName,
+ @{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+ @{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+ @{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}}
+ )
+ }
+ Add-PodeRoute -Path "/api/process-html" -Method "GET" -ScriptBlock {
+ Write-PodeHtmlResponse -Value (
+ Get-Process | Sort-Object -Descending CPU | Select-Object -First 15 ProcessName,
+ @{Name="ProcessorTime"; Expression={$_.TotalProcessorTime -replace "\.\d+$"}},
+ @{Name="Memory"; Expression={[string]([int]($_.WS / 1024kb))+"MB"}},
+ @{Label="RunTime"; Expression={((Get-Date) - $_.StartTime) -replace "\.\d+$"}} # Auto ConvertTo-Html
+ )
+ }
+ ### POST
+ Add-PodeRoute -Path "/api/service" -Method "POST" -ScriptBlock {
+ # https://pode.readthedocs.io/en/latest/Tutorials/WebEvent/
+ # $WebEvent | Out-Default
+ $Value = $WebEvent.Data["ServiceName"]
+ $Status = (Get-Service -Name $Value).Status
+ Write-PodeJsonResponse -Value @{
+ "Name"="$Value";
+ "Status"="$Status";
+ }
+ }
+}
+
+irm http://localhost:8080/api/service -Method Get
+irm http://localhost:8080/api/process -Method Get
+http://localhost:8080/api/process-html # использовать браузер
+irm http://localhost:8080/api/service -Method Post -Body @{"ServiceName" = "AnyDesk"}
+
# Selenium
.\nuget.exe install Selenium.WebDriver