捐血一袋救人一命

江蘇拙政園

江蘇 拙政園

全家福

日本 和歌山城

賞楓之旅

千燈 夕照

水鄉千燈

蘆洲 微風運河

破曉時分

2021年3月15日 星期一

PowerShell 的 Internet http(s)/Web 存取功能

  1. $ie = New-Object -com InternetExplorer.Application
  2. $Downloader = New-Object -TypeName System.Net.WebClient
  3. Invoke-WebRequest
  4. Invoke-RestMethod / Invoke-Method
  5. 透過 Selenium 操控瀏覽器,存取網站

第一種,只能操作 Internet Explorer,而且經常會莫名發生例外狀況,而無法使用 getElement(s)等相關方法
第二種,通常用在下載檔案,當你有確定的檔案網址時,就使用它來下載檔案/圖片/影片
第三種與第四種,通常用在存取網頁或呼叫API,如果遠端網站的資料是透過 Javascript AJAX 取得,那很可能就會抓不到資料

至於第五種,需要額外安裝Selenium WebDriver,不同瀏覽器需要安裝不同的版本;此外,當瀏覽器版本升級時,WebDriver也會需要相應升級

2021年3月2日 星期二

使用 Powershell 設定電腦環境

因為經常需要設定電腦,所以寫了個程式來設定電腦的環境,免得經常要手動設定,還容易忘記漏設定。

Param ([switch]$Verbose)
$VerboseStatus = $VerbosePreference
If($Verbose){
    $VerbosePreference = "Continue"
}
If(-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")){
    $ScriptFullPath = $MyInvocation.MyCommand.Definition
$arguments = "& '" + $ScriptFullPath + "'"
    # 另外以管理者身分執行 PowerShell,並載入 Script 來執行
Start-Process powershell -Verb runAs -ArgumentList $arguments
    # 中斷後面程式指令
Break
}
Write-Verbose "伺服器管理員不要每次開機都顯示"
New-ItemProperty -Path HKCU:\Software\Microsoft\ServerManager -Name DoNotOpenServerManagerAtLogon -PropertyType DWORD -Value “0x1” –Force | Out-Null
Write-Verbose "關閉 IE 增強安全性"
$AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
Set-ItemProperty -Path $AdminKey -Name "IsInstalled" -Value 0
$UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
Set-ItemProperty -Path $UserKey -Name "IsInstalled" -Value 0
Stop-Process -Name Explorer
Write-Verbose "關閉使用者存取控制(UAC)"
Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 00000000
Write-Verbose "設定微軟注音輸入法,預設為英文模式"
Set-ItemProperty "HKCU:\Software\Microsoft\IME\15.0\IMETC" -Name "Default Input Mode" -Value 0x00000001
Write-Verbose "設定電源模式-高效能"
& "powercfg.exe" /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
Write-Verbose "設定電源模式-高效能-永不關閉螢幕"
& "powercfg.exe" -change -monitor-timeout-ac 0
Write-Verbose "開機自動登入系統"
$usrname = 'user'
$password = 'mypasswd'
$RegistryLocation = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
Set-ItemProperty $RegistryLocation -Name 'AutoAdminLogon' -Value '1'
Set-ItemProperty $RegistryLocation -Name 'DefaultUsername' -Value "$usrname"
Set-ItemProperty $RegistryLocation -Name 'DefaultPassword' -Value "$password"
Write-Verbose "設定時區、指定校時伺服器並校時"
$TimeZone = "Taipei Standard Time"
$NTPServer1 = "time1.google.com"
$NTPServer2 = "time.windows.com"
$NTPServer3 = "time.nist.gov"
Set-TimeZone -Id $TimeZone -PassThru | Out-Null
Push-Location
Set-Location HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers
Set-ItemProperty . 0 $NTPServer1
Set-ItemProperty . 1 $NTPServer2
Set-ItemProperty . 2 $NTPServer3
Set-ItemProperty . "(Default)" "0"
Set-Location HKLM:\SYSTEM\CurrentControlSet\services\W32Time\Parameters
Set-ItemProperty . NtpServer $NTPServer1
Pop-Location
Stop-Service w32time
Start-Service w32time
Write-Verbose "變更網路區域為 Private (Not Public)"
$NetAdapter = (Get-NetConnectionProfile -IPv4Connectivity Internet).InterfaceIndex
Set-NetConnectionProfile -InterfaceIndex $NetAdapter -NetworkCategory Private
$VerbosePreference = $VerboseStatus
If($Host.Name -eq "ConsoleHost"){
    Pause
}

使用 PowerShell 清除暫存檔,並清除垃圾桶

先設定一個陣列 $tempfolders ,用來存放所有暫存檔路徑

然後使用 Remove-Item 指令來強制刪除檔案(force),包含子目錄(recurse)

因為有些暫存檔,有可能正在使用,是無法刪除的,會造成指令發出錯誤訊息,所以最後加上參數 -ErrorAction SilentlyContinue,當發生錯誤時,安靜地繼續執行指令

最後,清除垃圾桶,也是一樣的

$tempfolders = @("C:\Windows\Temp\*", "C:\Windows\Prefetch\*", "C:\Documents and Settings\*\Local Settings\temp\*", "C:\Users\*\Appdata\Local\Temp\*")

Remove-Item $tempfolders -force -recurse -ErrorAction SilentlyContinue

Clear-RecycleBin -Force -ErrorAction SilentlyContinue


如果要清除特別命名方式的檔案,或是不確定檔案位置的話,歡迎留言討論

使用 PowerShell 停用不安全的 SSL 2.0 3.0 & TLS 1.0 1.1 通訊協定

$Protocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1")
$EndPoints = @("Client", "Server")

Write-Verbose "停用 SSL 2.0 & 3.0 以及 TLS 1.0 & 1.1"

$Protocols | ForEach{
    $Protocol = $_
    If(!(Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol")){
        New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol" | Out-Null
    }
    $EndPoints | ForEach{
        $EndPoint = $_
        If(!(Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint")){
            New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" | Out-Null
        }
        Switch($EndPoint){
            "Client"{
                Try{
                    Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" -Name DisabledByDefault -ErrorAction Ignore
                    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" -Name DisabledByDefault -PropertyType DWORD -Value “0x1” –Force | Out-Null
                }Catch{
                    New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" -Name DisabledByDefault -PropertyType DWORD -Value “0x1” –Force | Out-Null
                }
            }
            "Server"{
                Try{
                    Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" -Name Enabled -ErrorAction Ignore
                    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" -Name Enabled -PropertyType DWORD -Value “0x0” –Force | Out-Null
                }Catch{
                    New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\$Protocol\$EndPoint" -Name Enabled -PropertyType DWORD -Value “0x0” –Force | Out-Null
                }
            }
        }
    }
}

2021年2月18日 星期四

使用 PowerShell 進行硬體資產調查

Windows 的 WMI, CIM 有很多資訊可以運用管理
例如軟硬體資產、系統資源效能、程式運作等

這次要做的是硬體資產調查,以前我有介紹使用 AIDA64 Business 來做資產調查,但這套軟體是要付費的。

所以不想要花錢,又要做到資產調查,就只好自己動作來

只要將 PowerShell 程式將資料寫入網芳檔案,使用群組政策,讓使用者開機就自動執行這個 PowerShell ,資料就會自動寫入檔案

使用 PowerShell 讀取 Synology NAS LDAP Server

網路上查到的PowerShell 讀取 LDAP 資訊,幾乎清一色都是讀取 Active Directory....

很少講到如何讀取 Linux LDAP Server

找了好久,終於找到 C# 讀取 LDAP 的資訊,改成 PowerShell 

使用 PowerShell 批次執行 IE ,自動登入 Synology NAS

這次會想寫這個程式,是因為公司打算將 G Workspace 轉移到 Synology NAS

公司本來也沒有使用 AD or LDAP 做驗證,打算將帳號整合到 LDAP 做未來準備。

轉移郵件的功能 MailPlus 本身的功能就很完整,不需要太多操心

但是Synology Drive 卻沒辦法自動批次轉移全公司的 Google Drive!

使用Cloud Sync ,必須讓使用者自行操作,也沒辦法限制使用者只能加入指定的 Google Workspace

幸運的是,Synology Active Backup for G Suite可以將全部使用者的Google Drive 都備份下來,只要把使用者備份檔案複製到使用者家目錄,就可以正常在Synology Drive 使用。

只是因為整合了 LDAP 驗證,所以家目錄變成 "帳號-LDAP uidNumber" 這樣的格式。

手動去建立家目錄也很麻煩(一兩百個帳號),用PowerShell 讀取 LDAP 也有點麻煩,所以最簡單的方法就是使用者登入Synology NAS,Synology NAS 會自動建立家目錄。

以下不多說,就直接看程式吧

之前在每個 Page 變動後,都去偵測 $ie.ReadyState = 4 或是 $ie.Busy = $False 程式才繼續執行,都會發生錯誤

後來改成檢查 $ie.Document.getElementById('ext-gen84') 是否為物件也會誤判

再改成檢查 $ie.Document.getElementById('ext-gen84') 是否存在,也還是會誤判

最後改成判斷 $ie.Document.getElementById('ext-gen84')的 Type 才成功。