Try   HackMD

用 Powershell 做 Windows 作業系統自動稽核檢查驗證 AutoAudit

使用情境

因應各種資安規範,常常需要針對個人電腦進行檢測,這邊整理了使用 cmd 或 powershell 方式取得電腦所有設定,減少要手動進去看設定的時間,也減少人員操作教學的繁瑣

適用環境

Windows 10, Windows Server 2012R或其他有支援愛Powershell的作業系統

使用方式

  1. 點擊 windows 開始工具列的放大鏡圖案 輸入 powershell 點擊後開啟應用程式

  1. 直接複製以下內文全文,貼到 powershell,觀看執行結果
function Auto-Audit { ## 取得電腦基本資訊 (電腦名稱、作業系統版本、CPU、記憶體、Bios、硬碟) function Get-ComputerInfo_Custom { $ComputerInfo = Get-ComputerInfo | Select-Object BiosSeralNumber,CsModel,CsName,CsPrimaryOwnerName,CsProcessors,OsName,CsPhyicallyInstalledMemory $PhysicalDisks = Get-PhysicalDisk | Select-Object DeviceId,FriendlyName,Size $ComputerInfoObject = [PSCustomObject]@{ 'Name' = $ComputerInfo.CsName 'OS' = $ComputerInfo.OsName 'Model' = $ComputerInfo.CsModel 'Owner' = $ComputerInfo.CsPrimaryOwnerName 'CPU' = $ComputerInfo.CsProcessors.Name 'RAM' = $ComputerInfo.CsPhyicallyInstalledMemory 'S/N' = $ComputerInfo.BiosSeralNumber } foreach ($Disk in $PhysicalDisks) { $ComputerInfoObject | Add-Member -NotePropertyName "Disk $($Disk.DeviceId)" -NotePropertyValue "$($Disk.FriendlyName), Size: $([int]($Disk.Size/1e9))GB" } $ComputerInfoObject } ## 取得所有磁碟目前容量和總容量 function Get-AllHardDiskSize { $alldisk = Get-WmiObject Win32_LogicalDisk | Select-Object DeviceID, Size, FreeSpace foreach ($disk in $alldisk){ try{ Write-Host ("DeviceID: " + $disk.DeviceID +"/ {0}GB free" -f [math]::truncate($disk.FreeSpace / 1GB) +"/" +"{0}GB total" -f [math]::truncate($disk.Size / 1GB)) } catch{} } } ## 取得管理者帳號與描述 function Get-Administrators { Get-LocalGroupMember -Group "Administrators" } ## 只取管理者帳號名稱 function Get-Administrators-OnlyAccountName{ (net localgroup administrators).where({$_ -match '-{79}'},'skipuntil') -notmatch '-{79}|The command completed' -notmatch '命令已經成功完成。' } ## 取得管理者帳號密碼原則與上次登入時間 function Get-Administrators-PasswordPolicy_LogonTime{ $ng = Get-Administrators-OnlyAccountName foreach ($i in $ng){ net user $i } } ## 取得管理者帳號密碼原則與上次登入時間 function Get-win32_quickfixengineering{ get-wmiobject -class win32_quickfixengineering } function Get-Banner { Write-Host "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" Write-Host "\ Auto-Audit 20220624 /" Write-Host " \ 自動稽核工具 20220624 /" Write-Host " \ https://hackmd.io/@Not/autoaudit / " Write-Host " \===========================================================/ " } <#-----------------------------------------------------------[Execution]------------------------------------------------------------#> Get-Banner Write-Host "===================================================================" Write-Host 'AutoAudit自動稽核開始' Write-Host "===================================================================" Write-Host '檢查電腦基本資訊 (電腦名稱、作業系統版本、 CPU、記憶體' Write-Host "===================================================================" Get-ComputerInfo_Custom Write-Host "" Write-Host "===================================================================" Write-Host '取得所有磁碟目前容量和總容量' Write-Host "===================================================================" Get-WmiObject -Class win32_logicaldisk | Format-Table DeviceId, @{n="Size (GB)";e={[math]::Round($_.Size/1GB,2)}},@{n="FreeSpace (GB)";e={[math]::Round($_.FreeSpace/1GB,2)}} Write-Host "" Write-Host "===================================================================" Write-Host '取得 Windows 更新安裝時間' Write-Host "===================================================================" Get-win32_quickfixengineering Write-Host "" Write-Host "===================================================================" Write-Host '取得時間伺服器 NTP 設定' Write-Host '如果顯示服務尚未啟動。則先到「服務」中,將 Windows Time 啟動,並將啟動類型設定為「自動(延遲開始)」(沒設定延遲開始,重開機似乎會無法啟動)' Write-Host "===================================================================" w32tm /query /peers Write-Host "" Write-Host "===================================================================" Write-Host '取得管理者帳號密碼原則與上次登入時間' Write-Host "===================================================================" Get-Administrators-PasswordPolicy_LogonTime Write-Host "" Write-Host "===================================================================" Write-Host '檢查防毒軟體是否保持開啟' Write-Host 'AntivirusEnabled 為防毒軟體啟動狀態,True 為有開啟' Write-Host 'RealTimeProtectionEnabled 為防毒軟體即時掃描保護狀態,True 為有開啟' Write-Host 'AntivirusSignatureLastUpdated 為病毒特徵碼最後更新時間' Write-Host 'AntispywareSignatureVersion 為病毒特徵碼更新版本號碼' Write-Host "===================================================================" Get-MpComputerStatus | Select AntivirusEnabled,RealTimeProtectionEnabled,AntivirusSignatureLastUpdated,AntispywareSignatureVersion Write-Host "" Write-Host "===================================================================" Write-Host '檢查螢幕保護程式設定狀態' Write-Host 'ScreenSaverActive 為有設定閒置後須開啟螢幕保護程式, True 為有開啟' Write-Host 'ScreenSaverSecure 為解除螢幕鎖定後需要輸入密碼, True 為有開啟' Write-Host 'ScreenSaverTimeout 為閒置多少秒數會進入螢幕保護程式' Write-Host "===================================================================" Get-CimInstance win32_desktop Write-Host "" Write-Host "===================================================================" Write-Host '取得目前電腦 IP 與 IPv4 Gateway IP,檢查目前使用的網路名稱' Write-Host "===================================================================" Write-Host "電腦IP:" Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex (Get-NetConnectionProfile | Select -expand InterfaceIndex) | Select -expand IPAddress Write-Host "IPv4 Gateway IP:" Get-NetIPConfiguration | Foreach IPv4DefaultGateway | Select -expand NextHop Get-NetConnectionProfile | Select Name,NetworkCategory,IPv4Connectivity,IPv6Connectivity Write-Host "" Write-Host "===================================================================" Write-Host '檢查 Windows 防火牆設定' Write-Host 'NotifyOnListen 為 主動通知有服務(程式)嘗試連線, True 每當程序或服務開始偵聽入站連接時,Windows 都會通知用戶' Write-Host "===================================================================" Get-NetFirewallProfile(Get-NetConnectionProfile | Select -expand NetworkCategory) | Select Name,Profile,Enabled,LogFileName,NotifyOnListen Write-Host "" Write-Host 'AutoAudit Finish 自動稽核完成' } Auto-Audit

以下是網站憑證專用的稽核項目

function Auto-Audit {
## 取得 https 網站憑證簽發者資訊與憑證起訖日
function GetWebsiteCertificateInfo{
      $url = "https://www.microsoft.com/:443"
      $WebRequest = [Net.WebRequest]::CreateHttp($url)
      $WebRequest.AllowAutoRedirect = $true
      $chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain
      
      #Request website
      try {$Response = $WebRequest.GetResponse()}
      catch {}
      
      #Creates Certificate
      $Certificate = $WebRequest.ServicePoint.Certificate.Handle
      $Issuer = $WebRequest.ServicePoint.Certificate.Issuer
      $Subject = $WebRequest.ServicePoint.Certificate.Subject
      $EffectiveDate = $WebRequest.ServicePoint.Certificate.GetEffectiveDateString()
      $ExpirationDate = $WebRequest.ServicePoint.Certificate.GetExpirationDateString()
	     
      ### Build chain
      $chain.Build($Certificate)
      write-host "憑證串鍊數量" $chain.ChainElements.Count #This returns "1" meaning none of the CA certs are included.
      write-host "憑證網站名稱" $Subject
      write-host "憑證簽發者" $chain.ChainElements.Certificate.Issuer
      write-host "憑證啟用日" $EffectiveDate
      write-host "憑證失效日" $ExpirationDate
	}
   <#-----------------------------------------------------------[Execution]------------------------------------------------------------#>

 	Write-Host '取得網站憑證資訊與憑證串鍊'
	Write-Host "==================================================================="
    GetWebsiteCertificateInfo
	Write-Host ""
	Write-Host "==================================================================="
}
Auto-Audit

時間伺服器 NTP

參考用伺服器
https://www.stdtime.gov.tw/chinese/bulletin/NTP promo.txt

開啟 cmd 使用以下指令觀看時間伺服器
w32tm /query /peers

如果正常會顯示網址,請比對網址是否與稽核要求之時間伺服器相同

對等: time.stdtime.gov.tw,0x9

更改時間伺服器 NTP

time.windows.com,0x1
https://suntargets.com/windows-設定為ntp-server/

故障排除

如果顯示服務尚未啟動。則先到「服務」中,將 Windows Time 啟動,並將啟動類型設定為「自動(延遲開始)」(沒設定延遲開始,重開機似乎會無法啟動)。

C:\Windows\system32>w32tm /query /peers
發生下列錯誤: 服務尚未啟動。 (0x80070426)

服務的內的位置

cmd取得硬碟總容量

for /f "tokens=1-3" %a in ('WMIC LOGICALDISK GET FreeSpace^,Name^,Size ^|FINDSTR /I /V "Name"') do @echo wsh.echo "%b" ^& " free=" ^& FormatNumber^(cdbl^(%a^)/1024/1024/1024, 2^)^& " GiB"^& " size=" ^& FormatNumber^(cdbl^(%c^)/1024/1024/1024, 2^)^& " GiB" > %temp%\tmp.vbs & @if not "%c"=="" @echo( & @cscript //nologo %temp%\tmp.vbs & del %temp%\tmp.vbs

powershell 取得C磁碟目前容量與總容量

$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'" | Select-Object Size, FreeSpace
Write-Host ("{0}GB free" -f [math]::truncate($disk.FreeSpace / 1GB) +"/" +"{0}GB total" -f [math]::truncate($disk.Size / 1GB)) 

取得 Windows 所有使用者帳號

使用 powershell 或 cmd都可以
開啟 powershell 視窗,輸入 Get-LocalUser 可以看到所有帳號

PS C:\Users\User1\Desktop> Get-LocalUser

Name               Enabled Description
----               ------- -----------
Administrator      False   管理電腦/網域的內建帳戶
DefaultAccount     False   由系統管理的使用者帳戶。
Guest              True    供來賓存取電腦/網域之用的內建帳戶
User1              True
WDAGUtilityAccount False   系統針對 Windows Defender 應用程式防護案例所管理及使用的使用者帳戶。

如果要看欄位可以用 select *

get-localuser | select *

如果要看單一使用者,可以用 -name "帳號名稱"

get-localuser -name "administrator" | select *

開啟cmd視窗,輸入net user可以看到帳號
輸入 net user > filename.txt 可以將檔案存到filename.txt

C:\Windows\System32>net user

\\DESKTOP-User1 的使用者帳戶

-------------------------------------------------------------------------------
Administrator            DefaultAccount           Guest
User1                 WDAGUtilityAccount
命令已經成功完成。

取得 Windows 管理者帳號

開啟 powershell 視窗,輸入 net localgroup Administrators 可以看到管理者群組的特權帳號

net localgroup Administrators

結果範例如下

PS C:\Users\User1> net localgroup Administrators
別名     Administrators
註解     Administrators 可以完全不受限制地存取電腦/網域

成員

-------------------------------------------------------------------------------
Administrator
User1
命令已經成功完成。

取得管理者帳號密碼原則與上次登入時間

$ng = (net localgroup administrators).where({$_ -match '-{79}'},'skipuntil') -notmatch '-{79}|The command completed' -notmatch '命令已經成功完成。'
  foreach ($i in $ng){
  	net user $i
  }		

取得事件檢視器事件列表

Get-EventLog -List

可以看到事件列表

PS C:\WINDOWS\system32> Get-EventLog -List

  Max(K) Retain OverflowAction        Entries Log
  ------ ------ --------------        ------- ---
  20,480      0 OverwriteAsNeeded      16,936 Application
   3,906      0 OverwriteAsNeeded           0 Cisco AnyConnect Secure Mobility Client
  20,480      0 OverwriteAsNeeded           0 HardwareEvents
     512      7 OverwriteOlder              0 Internet Explorer
  20,480      0 OverwriteAsNeeded           0 Key Management Service
     128      0 OverwriteAsNeeded          59 OAlerts
  20,480      0 OverwriteAsNeeded      30,156 Security
   8,192      0 OverwriteAsNeeded         525 Symantec Endpoint Protection Client
  20,480      0 OverwriteAsNeeded      20,104 System
  15,360      0 OverwriteAsNeeded         358 Windows PowerShell

取得事件檢視器指定類別(特定編號) 事件

這項功能可能要讀取安全性較高的Log(如 Security),需要管理者權限,因此要在開啟powershell前按右鍵,以系統管理者身分執行

以下為取得 4720 建立使用者帳戶的 Log

Get-EventLog -LogName Security -InstanceID 4720

結果範例如下

   Index Time          EntryType   Source                 InstanceID Message
   ----- ----          ---------   ------                 ---------- -------
  132626 十月 25 11:33 SuccessA... Microsoft-Windows...         4720 已建立使用者帳戶。...
Get-EventLog -LogName Security | ?{$_.InstanceID -eq 4720 -or $_.InstanceID -eq 4624}

取得事件檢視器中隨身碟的存取紀錄

預設沒有,想要有的話,需要先去事件檢視器開啟 追蹤紀錄 位置在 Application and Services Logs > Microsoft > Windows > DriverFrameworks-UserMode > Operational

之後在搜尋相關編號,usb連線有這些

  • 2003
  • 2004
  • 2006
  • 2010
  • 2100
  • 2101
  • 2105
  • 2106

拔除usb有這些

  • 2100
  • 2102

參考來源:
https://www.techrepublic.com/article/how-to-track-down-usb-flash-drive-usage-in-windows-10s-event-viewer/

取得所有 SQL Server 資料庫可以使用SQL登入的使用者

select * from master.sys.server_principals where type_desc= 'SQL_LOGIN' and is_disabled = 0

https://stackoverflow.com/a/18867117/4893973

取得單一 sql 資料庫的使用者帳號

use [DatabaseName]
select name as username,
       create_date,
       modify_date,
       type_desc as type,
       authentication_type_desc as authentication_type
from sys.database_principals
where type not in ('A', 'G', 'R', 'X')
      and sid is not null
      and name != 'guest'
      and name != 'dbo'
order by username;	

https://dataedo.com/kb/query/sql-server/list-users-in-database

用 Powershell 執行 sql 指令

需要安裝 SQLPS 模組後,才能使用 Powershel 執行 sql 指令 (invoke sql cmd),安裝模組的指令是 Import-Module
但 windows 預設會允許不執行 Import-Module 指令,直接執行的話會看到這樣的錯誤訊息

PS C:\Windows\System32\WindowsPowerShell\v1.0> Import-Module SQLPS
Import-Module : 因為這個系統上已停用指令碼執行,所以無法載入 C:\Program Files (x86)\Microsoft SQL Server\150\Tools\Powe
rShell\Modules\SQLPS\SqlPsPostScript.ps1 檔案。如需詳細資訊,請參閱 about_Execution_Policies,網址為 https:/go.microsof
t.com/fwlink/?LinkID=135170。
位於 線路:1 字元:1
+ Import-Module SQLPS
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : SecurityError: (:) [Import-Module], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess,Microsoft.PowerShell.Commands.ImportModuleCommand
    + 

所以需要先調整指令碼權限,輸入 Get-ExecutionPolicy -list 可以查看目前的權限設定

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

如果單獨輸入 Get-ExecutionPolicy,則可以收到 Restricted (受限制的) 的訊息,因此目前無法Import 模組

我們期望的是能夠在本機電腦上執行未簽署的腳本,從網路上或其他使用者取得的腳本需要簽署,可以使用 [以系統管理員身分執行] 選項啟動 PowerShell,然後使用下列命令將電腦上的執行原則變更為 RemoteSigned:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

這句指令就是說 將目前的使用者 (CurrentUser) 的腳本執行權限調整成 自己開發的或電腦上已經有的腳本不用數位簽署,但網路上抓來的就需要簽署了

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

執行原則變更
執行原則有助於防範您不信任的指令碼。如果變更執行原則,可能會使您接觸到 about_Execution_Policies 說明主題 (網址為
https:/go.microsoft.com/fwlink/?LinkID=135170) 中所述的安全性風險。您要變更執行原則嗎?
[Y] 是(Y)  [A] 全部皆是(A)  [N] 否(N)  [L] 全部皆否(L)  [S] 暫停(S)  [?] 說明 (預設值為 "N"):    

以上請輸入 Y

完成後,可以再次輸入 Get-ExecutionPolicy -list,會看到變成了 CurrentUser RemoteSigned,其他沒有變更,就是完成了

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       Undefined

如果稍後安裝完 SQLPS 模組,覺得有風險想要關掉,可以再次輸入指令改成原本的

Set-ExecutionPolicy Undefined -Scope CurrentUser

或是明確告知禁止執行 Restricted

Set-ExecutionPolicy Restricted -Scope CurrentUser

參考文件:about_Signing 關於簽署
受限制的執行原則不允許執行任何腳本。 AllSigned和RemoteSigned執行原則可防止 PowerShell 執行沒有數位簽章的腳本。
https://docs.microsoft.com/zh-tw/powershell/module/microsoft.powershell.core/about/about_signing?view=powershell-7.2

安裝 SQLPS 模組

Import-Module SQLPS

安裝後不會有其他訊息

PS C:\Windows\System32\WindowsPowerShell\v1.0> Import-Module SQLPS PS C:\Windows\System32\WindowsPowerShell\v1.0>

模組安裝說明
https://www.powershellgallery.com/packages/Sqlserver/21.1.18256
官方文件
https://docs.microsoft.com/zh-tw/sql/powershell/download-sql-server-ps-module?view=sql-server-ver16

檢測是否能用 powershell 對 sql server 資料庫 執行 sql 語法

這邊使用 windows 驗證,所以無需另外登入,只要把資料庫連線路徑改成自己的即可,路徑可以透過成功連線過的 sql server 資料庫圖形介面工具直接看,以這邊來說就是伺服器名稱

範例語法如下

Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery" -ServerInstance "ServerIP\DBServerInstance"

我實際執行的如下

Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery" -ServerInstance "localhost\sqlexpress"

收到的回應範例,這樣就能確定指令執行成功了

PS C:\Windows\System32\WindowsPowerShell\v1.0> Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery" -ServerInstance "localhost\sqlexpress" TimeOfQuery ----------- 2022/8/19 下午 08:48:36

結合我們其他實務的例子,我們希望直接用 powershell 取得資料庫所有帳號,而不透過圖形工具,可以利用以下語法

Invoke-Sqlcmd -Query "select * from master.sys.server_principals where type_desc= 'SQL_LOGIN' and is_disabled = 0" -ServerInstance "localhost\sqlexpress"

執行後的結果如下

PS C:\Windows\System32\WindowsPowerShell\v1.0> Invoke-Sqlcmd -Query "select * from master.sys.server_principals where type_desc= 'SQL_LOGIN' and is_disabled = 0" -ServerInstance "localhost\sqlexpress"

name                  : MyDataBaseManagerAccount
principal_id          : 266
sid                   : {55, 67, 221, 248...}
type                  : S
type_desc             : SQL_LOGIN
is_disabled           : False
create_date           : 2021/6/19 下午 07:59:55
modify_date           : 2022/7/17 下午 02:20:02
default_database_name : master
default_language_name : 繁體中文
credential_id         :
owning_principal_id   :
is_fixed_role         : False

https憑證序號

從網頁上方按憑證

取得 https 網站憑證簽發者資訊與憑證起訖日

$url = "https://www.microsoft.com/:443"
$WebRequest = [Net.WebRequest]::CreateHttp($url)
$WebRequest.AllowAutoRedirect = $true
$chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain

#Request website
try {$Response = $WebRequest.GetResponse()}
catch {}

#Creates Certificate
$Certificate = $WebRequest.ServicePoint.Certificate.Handle
$Issuer = $WebRequest.ServicePoint.Certificate.Issuer
$Subject = $WebRequest.ServicePoint.Certificate.Subject
$EffectiveDate = $WebRequest.ServicePoint.Certificate.GetEffectiveDateString()
$ExpirationDate = $WebRequest.ServicePoint.Certificate.GetExpirationDateString()
   
### Build chain
$chain.Build($Certificate)
write-host "憑證串鍊數量" $chain.ChainElements.Count #This returns "1" meaning none of the CA certs are included.
write-host "憑證網站名稱" $Subject
write-host "憑證簽發者" $chain.ChainElements.Certificate.Issuer
write-host "憑證啟用日" $EffectiveDate
write-host "憑證失效日" $ExpirationDate

取得電腦所有安裝的軟體(照名稱排序)

語法較長但速度比較快

$registry_paths = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
Write-Verbose "Reading installed software from registry."
@(
    foreach ($registry_path in $registry_paths) {
        $subkeys = Get-ChildItem -Path $registry_path -ErrorAction SilentlyContinue

        if ($subkeys) {
            ForEach ($key in $subkeys) {
                $DisplayName = $key.getValue('DisplayName')

                if ($null -notlike $DisplayName) {
                    $DisplayVersion = $key.GetValue('DisplayVersion')

                    [PSCustomObject]@{
                        PSTypeName      = 'System.Software.Inventory'
                        DisplayName     = $DisplayName.Trim()
                        DisplayVersion  = $DisplayVersion
                        NameVersionPair = $DisplayName.Trim() + $DisplayVersion
                    }
                }
            }
        }
    }
) | Sort-Object NameVersionPair -Unique

取得電腦所有安裝的軟體

開啟 powershell輸入以下指令,可觀看所有安裝的軟體,語法較短但也跑比較久

Get-WmiObject -Class Win32_Product
Get-WmiObject -Class Win32_Product | select Name, Version

參考來源
https://www.codetwo.com/admins-blog/how-to-check-installed-software-version/

將 powershell 的結果輸出到純文字文件

先寫上指令,在指令後面加上
=cmd | Out-File -FilePath software.txt

完整範例如下

Get-WmiObject -Class Win32_Product | Out-File -FilePath software.txt

匯出成 csv的範例

Get-WmiObject Win32_Product | Sort-Object Name | Select Name,version,Vendor |export-csv myprogramlist.csv

參考來源
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-file?view=powershell-7.1

檢查電腦狀態

Get-MpComputerStatus

檢查防毒軟體是否正常運作

Get-MpComputerStatus | Select AntivirusEnabled,RealTimeProtectionEnabled,AntivirusSignatureLastUpdated,AntispywareSignatureVersion

查詢使用者上次密碼變更情形及上次登入時間

net user Myaccount帳號名稱

C:\Users\帳號> net user Myaccount帳號名稱
使用者名稱             Myaccount帳號名稱
全名
註解
使用者的註解
國家/區域碼            000 (系統預設值)
帳戶使用中             Yes
帳戶到期               從不

上次設定密碼           2016/11/16 下午 05:31:13
密碼到期               從不
可變更密碼             2016/11/16 下午 05:31:13
請輸入密碼             No
使用者可以變更密碼     Yes

容許的工作站           全部
登入指令檔
使用者設定檔
主目錄
上次登入時間           2021/10/21 下午 03:54:18

可容許的登入時數       全部

本機群組會員           *Administrators *Remote Desktop Users *Users
全域群組會員           *None
命令已經成功完成。

參考文件

https://xyz.cinc.biz/2015/04/windows-w32tm.html


取得Windows Update 最近更新資訊

## Convert Wua History ResultCode to a Name # 0, and 5 are not used for history # See https://msdn.microsoft.com/en-us/library/windows/desktop/aa387095(v=vs.85).aspx function Convert-WuaResultCodeToName { param( [Parameter(Mandatory=$true)] [int] $ResultCode ) $Result = $ResultCode switch($ResultCode) { 2{$Result = "Succeeded"} 3{$Result = "Succeeded With Errors"} 4{$Result = "Failed"} } return $Result } function Get-WuaHistory { # Get a WUA Session $session = (New-Object -ComObject 'Microsoft.Update.Session') # Query the latest 1000 History starting with the first recordp $history = $session.QueryHistory("",0,50) | ForEach-Object { $Result = Convert-WuaResultCodeToName -ResultCode $_.ResultCode # Make the properties hidden in com properties visible. $_ | Add-Member -MemberType NoteProperty -Value $Result -Name Result $Product = $_.Categories | Where-Object {$_.Type -eq 'Product'} | Select-Object -First 1 -ExpandProperty Name $_ | Add-Member -MemberType NoteProperty -Value $_.UpdateIdentity.UpdateId -Name UpdateId $_ | Add-Member -MemberType NoteProperty -Value $_.UpdateIdentity.RevisionNumber -Name RevisionNumber $_ | Add-Member -MemberType NoteProperty -Value $Product -Name Product -PassThru Write-Output $_ } #Remove null records and only return the fields we want $history | Where-Object {![String]::IsNullOrWhiteSpace($_.title)} | Select-Object Result, Date, Title, SupportUrl, Product, UpdateId, RevisionNumber } Get-WuaHistory | Format-Table

單次允許執行 powershell 的批次檔

powershell -ExecutionPolicy Bypass -File C:\pw\ps.ps1

在工作排程器的設定位置

比較兩個資料夾檔案差異

robocopy C:\fso C:\fso_BackUp /MIR
第一版,缺點是如果來源資料夾有多 or 目的資料夾有少 無法辨識

$SourceDocs = Get-ChildItem -Path C:\fso | foreach  {Get-FileHash -Path $_.FullName}
$DestDocs = Get-ChildItem -Path C:\fso_BackUp | foreach  {Get-FileHash -Path $_.FullName}
$LogPath = ("C:\pw\log.txt") 
Get-Date | Add-Content $LogPath
(Compare-Object -ReferenceObject $SourceDocs -DifferenceObject $DestDocs  -Property hash -PassThru).Path | Add-Content -encoding utf8 -Path $LogPath
"---------End-----------------" | Add-Content C:\pw\log.txt

How To Compare the Contents of Two Folders with PowerShell
https://mcpmag.com/articles/2016/04/14/contents-of-two-folders-with-powershell.aspx

附加文字 How to Append Data to a Text File Using PowerShell
https://www.faqforge.com/powershell/append-data-text-file-using-powershell/

寫入檔案(覆蓋) Out-File Module:Microsoft.PowerShell.Utility
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-file?view=powershell-7.1

查詢這台電腦目前有哪些使用者登入

quser

PS C:\Users\Not> quser
 使用者名稱            工作階段名稱    識別碼 狀態    閒置時間   登入時間
>Not               console             1  使用中      無   2022/8/18 下午 03:09

待開發的新需求

檢查 iis session timeout 以及自動設定

https://serverfault.com/questions/829320/set-iis-website-classic-asp-session-timeout-using-powershell

檢查 windows 事件檢視器 容量、保存多久、超過是覆蓋還是封存
https://www.thelazyitadmin.com/archive-windows-security-event-log/

利用檔案檔頭 file header 查詢檔案格式

使用方式:先 copy 底下的powershell指令執行,之後再輸入 Check-Header 檔名
例如有一個不知道檔案副檔名的 1.xxx,只要輸入 Check-Header .\1.xxx,會看到回傳 pdf 的文字訊息

看檔案 header 16進位編碼可參考這個網站 Digital Forensics Magic Numbersnumber

以下為辨識用的powershell

# fixed by not 20230616
# from https://github.com/gangstanthony/PowerShell/blob/master/Check-Header.ps1
# http://learningpcs.blogspot.com/2012/07/powershell-v3-check-file-headers.html
# https://en.wikipedia.org/wiki/List_of_file_signatures
# http://www.garykessler.net/library/file_sigs.html


function Check-Header {
    param (
        $path
    )
    
    $path = Resolve-Path $path

    # Hexidecimal signatures for expected files
    $known = @'
"Extension","Header"
"3gp","66 74 79 70 33 67"
"7z","37 7A BC AF 27 1C"
"8sv","38 53 56 58"
"8svx","46 4F 52 4D nn nn nn nn"
"acbm","46 4F 52 4D nn nn nn nn"
"aif","41 49 46 46"
"aiff","46 4F 52 4D nn nn nn nn"
"anbm","46 4F 52 4D nn nn nn nn"
"anim","46 4F 52 4D nn nn nn nn "
"asf","30 26 B2 75 8E 66 CF 11"
"avi","52 49 46 46 nn nn nn nn "
"bac","42 41 43 4B 4D 49 4B 45"
"bpg","42 50 47 FB"
"cab","4D 53 43 46"
"cin","80 2A 5F D7"
"class","CA FE BA BE"
"cmus","46 4F 52 4D nn nn nn nn"
"cr2","49 49 2A 00 10 00 00 00"
"crx","43 72 32 34"
"cwk","05 07 00 00 42 4F 42 4F"
"cwk","06 07 E1 00 42 4F 42 4F"
"dat","50 4D 4F 43 43 4D 4F 43"
"DBA","BE BA FE CA"
"DBA","00 01 42 44"
"dex","64 65 78 0A 30 33 35 00"
"djvu","41 54 26 54 46 4F 52 4D nn nn nn nn 44 4A 56"
"dmg","78 01 73 0D 62 62 60"
"doc","D0 CF 11 E0 A1 B1 1A E1"
"dpx","53 44 50 58"
"exr","76 2F 31 01"
"fax","46 41 58 58"
"faxx","46 4F 52 4D nn nn nn nn"
"fh8","41 47 44 33"
"fits","53 49 4D 50 4C 45 20 20"
"flac","66 4C 61 43"
"flif","46 4C 49 46"
"ftxt","46 4F 52 4D nn nn nn nn"
"gif","47 49 46 38 37 61"
"ico","00 00 01 00"
"idx","49 4E 44 58"
"iff","41 43 42 4D"
"iff","41 4E 42 4D"
"iff","41 4E 49 4D"
"iff","46 4F 52 4D nn nn nn nn"
"ilbm","46 4F 52 4D nn nn nn nn"
"iso","43 44 30 30 31"
"jpg","FF D8 FF DB"
"lbm","49 4C 42 4D"
"lz","4C 5A 49 50"
"lz4","04 22 4D 18"
"mid","4D 54 68 64"
"mkv","1A 45 DF A3"
"MLV","4D 4C 56 49"
"mus","43 4D 55 53"
"nes","4E 45 53 1A"
"ods","50 4B 05 06"
"ogg","4F 67 67 53"
"PDB","00 00 00 00 00 00 00 00"
"pdf","25 50 44 46"
"png","89 50 4E 47 0D 0A 1A 0A"
"ps","25 21 50 53"
"psd","38 42 50 53"
"rar","52 61 72 21 1A 07 00"
"rar","52 61 72 21 1A 07 01 00"
"smu","53 4D 55 53"
"smus","46 4F 52 4D nn nn nn nn"
"stg","4D 49 4C 20"
"tar","75 73 74 61 72 00 30 30"
"TDA","00 01 44 54"
"tif","49 49 2A 00"
"toast","45 52 02 00 00 00"
"tox","74 6F 78 33"
"txt","46 54 58 54"
"vsdx","50 4B 07 08"
"wav","52 49 46 46 nn nn nn nn"
"wma","A6 D9 00 AA 00 62 CE 6C"
"xar","78 61 72 21"
"yuv","59 55 56 4E"
"yuvn","46 4F 52 4D nn nn nn nn"
"zip","50 4B 03 04"

'@ | ConvertFrom-Csv | sort {$_.header.length} -Descending
    
    $known | % {$_.header = $_.header -replace '\s'}
    
    try {
        # Get content of each file (up to 4 bytes) for analysis
        $HeaderAsHexString = New-Object System.Text.StringBuilder
        [Byte[]](Get-Content -Path $path -TotalCount 4 -Encoding Byte -ea Stop) | % {
            if (("{0:X}" -f $_).length -eq 1) {
                $null = $HeaderAsHexString.Append('0{0:X}' -f $_)
            } else {
                $null = $HeaderAsHexString.Append('{0:X}' -f $_)
            }
        }
      
        # Validate file header
        # might change .startswith() to -match.
        # might remove 'select -f 1' to get all possible matching extensions, or just somehow make it a better match.
        $known | ? {$_.header.startswith($HeaderAsHexString.ToString())} | select -f 1 | % {$_.extension}
    } catch {}
}
tags: 資安