因應各種資安規範,常常需要針對個人電腦進行檢測,這邊整理了使用 cmd 或 powershell 方式取得電腦所有設定,減少要手動進去看設定的時間,也減少人員操作教學的繁瑣
Windows 10, Windows Server 2012R或其他有支援愛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
參考用伺服器
https://www.stdtime.gov.tw/chinese/bulletin/NTP promo.txt
開啟 cmd 使用以下指令觀看時間伺服器
w32tm /query /peers
如果正常會顯示網址,請比對網址是否與稽核要求之時間伺服器相同
對等: time.stdtime.gov.tw,0x9
time.windows.com,0x1
https://suntargets.com/windows-設定為ntp-server/
如果顯示服務尚未啟動。則先到「服務」中,將 Windows Time 啟動,並將啟動類型設定為「自動(延遲開始)」(沒設定延遲開始,重開機似乎會無法啟動)。
C:\Windows\system32>w32tm /query /peers
發生下列錯誤: 服務尚未啟動。 (0x80070426)
服務的內的位置
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
$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))
使用 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
命令已經成功完成。
開啟 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連線有這些
拔除usb有這些
select * from master.sys.server_principals where type_desc= 'SQL_LOGIN' and is_disabled = 0
https://stackoverflow.com/a/18867117/4893973
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
需要安裝 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
從網頁上方按憑證
$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/
先寫上指令,在指令後面加上
=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
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
## 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 -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 以及自動設定
檢查 windows 事件檢視器 容量、保存多久、超過是覆蓋還是封存
https://www.thelazyitadmin.com/archive-windows-security-event-log/
使用方式:先 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 {}
}
資安