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 @@ -![Image alt](https://github.com/Lifailon/PowerShell-Commands/blob/rsa/Logo/PowerShell-Commands.png) +![Image alt](https://github.com/Lifailon/PS-Commands/blob/rsa/Logo/PowerShell-Commands.png) - [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