Friday, May 31, 2019

Powershell: Compare-Object to analyze two files

Displaying differences between two files like Linux 'diff' command, you can use Powershell Compare-Object cmdlet.

# You do not find any identical differences with just giving file names.
PS > Compare-Object .\sample01.txt .\sample02.txt

InputObject SideIndicator
----------- -------------
.\sample02.txt =>
.\sample01.txt <=


# You can identify differences between two files with following method.
PS > Compare-Object (Get-Content .\sample01.txt) (Get-Content .\sample02.txt)

InputObject SideIndicator
----------- -------------
efg =>
hijkl =>
efgh <=
ijkl <=

Thursday, May 30, 2019

Powershell: Get-Command / Get-Module

Get-Command allows you to check whether the specific cmdlet is available on your Powershell environment.
Each cmdlets are provided by Powershell module, and it belongs to the module.


Invoke-RestMethod is provided by Microsoft.PowerShell.Utility module
PS Env:\> Get-Command Invoke-RestMethod

CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Invoke-RestMethod 3.1.0.0 Microsoft.PowerShell.Utility


You can see a number of cmdlets are provided by Microsoft.PowerShell.Utility with 'Get-Module' cmdlet.
PS Env:\> (Get-Module Microsoft.PowerShell.Utility).ExportedCmdlets

Key Value
--- -----
Add-Member Add-Member
Add-Type Add-Type
Clear-Variable Clear-Variable
Compare-Object Compare-Object
Convert-String Convert-String
ConvertFrom-Csv ConvertFrom-Csv
ConvertFrom-Json ConvertFrom-Json
ConvertFrom-String ConvertFrom-String
ConvertFrom-StringData ConvertFrom-StringData
ConvertTo-Csv ConvertTo-Csv
ConvertTo-Html ConvertTo-Html
ConvertTo-Json ConvertTo-Json
ConvertTo-Xml ConvertTo-Xml
Debug-Runspace Debug-Runspace
Disable-PSBreakpoint Disable-PSBreakpoint
Disable-RunspaceDebug Disable-RunspaceDebug
Enable-PSBreakpoint Enable-PSBreakpoint
Enable-RunspaceDebug Enable-RunspaceDebug
Export-Alias Export-Alias

Saturday, May 18, 2019

Powershell: Import-CSV

# -Delimeter option allows you to set separator value other than comma.
# Use -Encoding option to specify imported csv character set. The default is UTF8 without BOM.
> $test=Import-Csv .\KEN_ALL.CSV -Encoding Default

# Once you imported, you can manipulate the variable as array object.
> $test.Count
124267


> $test[112200]

a : 40133
b : 810
c : 8100001
d : フクオカケン
e : フクオカシチュウオウク
f : テンジン
g : 福岡県
h : 福岡市中央区
i : 天神
j : 0
k : 0
l : 1
m : 0
n : 0
o : 0


> $test | where { $_.b -match "^818" } | Format-Table -Property c ,g,h,i

c g h i
- - - -
8180000 福岡県 筑紫野市 以下に掲載がない場合
8180011 福岡県 筑紫野市 阿志岐
8180012 福岡県 筑紫野市 天山
8180068 福岡県 筑紫野市 石崎
8180014 福岡県 筑紫野市 牛島
8180034 福岡県 筑紫野市 美しが丘南


# Now you want to clear the variable!

> $test.Clear()

Wednesday, May 15, 2019

Powershell: Securely pass credentials to script

Embedding user credential on the Powershell script is sometimes regarded as security breach, and severely punished when it was revealed.
It would be better solution to use ConvertFrom-SecureString to encrypt secure string, and ConvertTo-SecureString to decrypt.

Overall steps would be like following:
1. Create password with 'Secure string object'.
2. Create encrypted password file with [1] by 'ConvertFrom-SecureString' cmdlet.
3. Decrypt [2] file to get password as 'Secure string object' by runnning 'ConvertTo-SecureString' cmdlet.


#Create password as 'Secure string object'
> $password=Read-Host -AsSecureString "Enter Password"
Enter Password: ***********

#You can see the password you typed became 'Secure string object'
> $password
System.Security.SecureString

#Save 'Secure string object' with encryption
> $password | ConvertFrom-SecureString | Out-File password-file.txt

#You can see the password was encrypted and sotred in file
> cat .\password-file.txt
01000000d08c9ddf0115d1118c7a00c04fc297eb0100000052be3e1d12e24643a99e5adca0fccae300000000020000000000106

#Now you can decrypt the password-file and can be used for credential.
> $User = "somedomain\yangjie"
> $PWord = Get-Content .\password-file.txt | ConvertTo-SecureString
> $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord

Monday, May 13, 2019

Powershell: Start-Job

Like put an ampersand sign on the end of Linux command statement, Powershell 'Start-Job' cmdlet allows you to run command that you specified as background job.

If you pass it to 'Wait-Job', prompt rather waits until the job done.


#-ScriptBlock to specify command/script to run
#-Name to specify friendly name of the job
> Start-Job -ScriptBlock { systeminfo.exe } -Name JobSysInfo

Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 JobSysInfo BackgroundJob Completed True localhost systeminfo.exe

# Get Detailed property list
> (Get-Job -id 1) | Format-List -Property *

State : Completed
HasMoreData : False
StatusMessage :
Location : localhost
Command : systeminfo.exe
JobStateInfo : Completed
Finished : System.Threading.ManualResetEvent
InstanceId : 57241598-0879-41eb-93c6-58e65f4b09e2
Id : 1
Name : JobSysInfo
ChildJobs : {Job2}
PSBeginTime : 2019/05/14 12:01:20
PSEndTime : 2019/05/14 12:01:24
PSJobTypeName : BackgroundJob
Output : {}
Error : {}
Progress : {}
Verbose : {}
Debug : {}
Warning : {}
Information : {}



#Job result can be shown by Receive-Job cmdlet
> Receive-Job (Get-Job -id 1) ホスト名: DESKTOP-0TV9VQT
OS 名: Microsoft Windows 10 Home
OS バージョン: 10.0.17134 N/A ビルド 17134
OS 製造元: Microsoft Corporation
OS 構成: スタンドアロン ワークステーション


#Long running job can be stopped by StopJob method.
> (Get-Job -id 1).StopJob()

Sunday, May 12, 2019

Powershell: Start-Transcript

Due to security reason or audit purpose, operators are required to record an activity on the terminal.
Powershell provides session record/logging command, defined as 'Start-Transcript'.

> Start-Transcript -Path "pshell.log" -NoClobber
トランスクリプトが開始されました。出力ファイル: pshell.log

> ls

ディレクトリ: C:\Users\drago\

Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 2018/12/11 10:51 4289310 IMG_20181211_194816.jpg
------ 2018/12/11 10:51 2320769 IMG_20181211_194840.jpg
------ 2018/12/11 10:51 3137062 IMG_20181211_194852.jpg
------ 2018/12/11 10:51 3223160 IMG_20181211_194856.jpg
------ 2018/12/11 10:51 3470993 IMG_20181211_194902.jpg
------ 2018/12/11 10:51 3977489 IMG_20181211_195032.jpg
-a---- 2018/06/15 14:23 52193 portrait-2.zip
-a---- 2019/05/12 23:12 759 pshell.log


>
>
> Stop-Transcript
**********************
Windows PowerShell トランスクリプト終了
終了時刻: 20190512231418
**********************



Add '-NoClobber' option for preventing the log be overwritten.

You can check the log file that you specified on '-Path' parameter of the command.
You can terminate the session, or just gently type 'Stop-Transcript' to end it.

Saturday, May 11, 2019

PowerShell: Measure-Command


This is how we can measure a command or script block run on PowerShell like Linux time command.



PS C:\Users\drago> $i=0; Measure-Command { for ($i=1; $i -le 10; $i++) { Write-Progress -Activity "measure running time

" -Status "$i% completed" -PercentComplete $i; sleep 1;

>> }} | Select-Object Seconds




Seconds

-------

10

Powershell: Get-EventLog

Using Get-EventLog cmdlet is sometimes more efficient way to check event log than open Event Viewer.


PS C:\Users\drago> Get-EventLog -LogName System -Newest 5

Index Time EntryType Source InstanceID Message
----- ---- --------- ------ ---------- -------

12650 5 10 19:02 Information Microsoft-Windows... 1 システムは低電力状態から再開しました。...

12649 5 10 19:02 Information Microsoft-Windows... 1 CVE の検出の可能性: 2019-05-10T10:02:30.5000000..

12648 5 10 19:02 Information EventLog 2147489661 システムの稼働時間は 10367070 秒です。

12647 5 09 23:57 Information Microsoft-Windows... 107 ソース 'Microsoft-Windows-Kernel-Power' のイベ...

12646 5 09 23:57 Information Microsoft-Windows... 42 ソース 'Microsoft-Windows-Kernel-Power' のイベ..



It also can filter logs with '-EntryType' or '-Source'.
I tried to retrieve System Error log other than "DCOM" source type as follow.


PS C:\Users\drago> Get-EventLog -LogName System -EntryType Error | where {$_.Source -notlike "dcom"} | Select-Object -First 5


Index Time EntryType Source InstanceID Message

----- ---- --------- ------ ---------- -------

12355 5 01 14:16 Error Microsoft-Windows... 20 インストールの失敗: エラー 0x80073d02 で次の更...

11835 4 17 13:50 Error VBoxNetLwf 3221487628 ドライバーは \Device\VBoxNetLwf で内部ドライバ...

11834 4 17 13:48 Error VBoxNetLwf 3221487628 ドライバーは \Device\VBoxNetLwf で内部ドライバ...

11833 4 17 13:48 Error VBoxNetLwf 3221487628 ドライバーは \Device\VBoxNetLwf で内部ドライバ...

11765 4 14 20:49 Error Microsoft-Windows... 20 インストールの失敗: エラー 0x80073d02 で次の更...





Here is how we can monitor system event log with retrieving it every 5 seconds.

PS C:\Users\drago> while(1){
>> Get-EventLog -LogName System -Newest 10 ;
>> sleep 5;
>> cls;
>> }

Powershell: Display progress indicater

Implementing progress bar sometimes would be efficient as we can identify if the task is still ongoing or unexpectedly hunged.

Let's try 'Write-Progress' cmdlet.


for ($i = 1; $i -le 50; $i++ )
{
    Write-Progress -Activity "Title of progress bar" -Status "$i% Complete:" -PercentComplete $i;

# Do something, such as file copy or time consuming tasks etc..
    Sleep 2;

}


Powershell: [System.Version]$_

Use version class for comparing dotted numbers, such as IP address.

PS C:\Users\drago> $IPAddresses = @(
>> '10.10.12.13',
>> '10.11.102.3',
>> '10.12.10.26',
>> '10.13.10.252'
>> );


PS C:\Users\drago> $IPAddresses | Sort { [System.Version]$_ }

10.10.12.13
10.11.102.3
10.12.10.26
10.13.10.252


#powershell, #dotnetframework, #windows

Powershell: curl equivalent command

If your Powershell version is higher than 3, 'Invoke-RestMethod' command is available as alternative method of Unix/Linux curl command.

>> Check the version of your powershell.


PS C:\Users\drago> $PSVersionTable.PSVersion | Select-Object major

Major
-----
5


>> And just type URI whatever you want to retrieve
PS C:\Users\drago> Invoke-RestMethod -Uri https://www.msn.com -Method Get




I tried to process the result with piped 'Select-String', though couldn't filter the result.


The command is not so easy as curl, further study is still needed for it.