A configuration and security inspection tool written in Go
Author: Pecezen.org
Platform: Windows
Language: Go
When preparing for ISO/IEC 27001 certification, under control 8.9 Configuration Management, auditors commonly review the following aspects.
- The operating system versions of servers and personal computers.
- Whether any unauthorized software has been installed.
- Whether firewall and antivirus software are properly enabled.
- Whether any unnecessary system services are running.
So I decided to write a simple configuration and security inspection tool. I recently had some free time, so I’m sharing it here for everyone’s reference.
✅ Tool Features Overview:
- 🖥️ Hardware Information
- 🧩 Operating System (OS) Information
- 📦 Installed Software List
- 🛡️ Antivirus Status
- 🔥 Firewall Status
- ⚙️ System Services Status
- 📤 Supports CSV Export for auditing or record-keeping
- 🌐 Multi-language Interface (Traditional Chinese / English / Japanese / German)
🖥️ User Interface:

💾 Download the Windows Version
You can use the source code below to compile the program yourself, but we’ve also included a ready-to-run Windows executable for your convenience.:
Download
The downloaded file is a compressed archive.
The extraction password is: pecezen.org
🔗Source Code
package main
import (
"bytes"
"encoding/csv"
"image/color"
"os/exec"
"strings"
"syscall"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
/*
=========================
Theme & Language (i18n)
=========================
*/
type readableTheme struct{}
func (readableTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
if n == theme.ColorNameDisabled {
return color.NRGBA{0, 0, 0, 255}
}
return theme.DefaultTheme().Color(n, v)
}
func (readableTheme) Font(s fyne.TextStyle) fyne.Resource { return theme.DefaultTheme().Font(s) }
func (readableTheme) Icon(n fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(n) }
func (readableTheme) Size(n fyne.ThemeSizeName) float32 { return theme.DefaultTheme().Size(n) }
type Lang string
const (
LangZHTW Lang = "zh-TW"
LangEN Lang = "en"
LangJA Lang = "ja"
LangDE Lang = "de"
)
var langOptions = []string{"繁體中文", "English", "日本語", "Deutsch"}
var langMap = map[string]Lang{
"繁體中文": LangZHTW,
"English": LangEN,
"日本語": LangJA,
"Deutsch": LangDE,
}
const prefLangKey = "SelectedLanguage"
type i18n struct{ lang Lang }
func (i i18n) tr(key string) string {
table := map[string]map[Lang]string{
"app.title": {
LangZHTW: "組態與安全性檢測工具 V1.0",
LangEN: "Config & Security Audit Tool V1.0",
LangJA: "構成とセキュリティ診断 V1.0",
LangDE: "Konfigurations- und Sicherheits-Audit-Tool V1.0",
},
"tab.hardware": {
LangZHTW: "硬體資訊", LangEN: "Hardware Info", LangJA: "ハードウェア情報", LangDE: "Hardware-Info",
},
"tab.os": {
LangZHTW: "OS 資訊", LangEN: "OS Info", LangJA: "OS 情報", LangDE: "OS-Info",
},
"tab.apps": {
LangZHTW: "軟體清單", LangEN: "Software", LangJA: "ソフト一覧", LangDE: "Softwareliste",
},
"tab.av": {
LangZHTW: "防毒狀態", LangEN: "Antivirus", LangJA: "ウイルス対策", LangDE: "Virenschutz",
},
"tab.firewall": {
LangZHTW: "防火牆", LangEN: "Firewall", LangJA: "防火壁", LangDE: "Firewall",
},
"tab.service": {
LangZHTW: "系統服務", LangEN: "Services", LangJA: "サービス", LangDE: "Systemdienste",
},
"tab.policy": {
LangZHTW: "安全原則", LangEN: "Policies", LangJA: "ポリシー", LangDE: "Sicherheitsrichtlinien",
},
"btn.export": {
LangZHTW: "匯出目前分頁 CSV",
LangEN: "Export Current CSV",
LangJA: "現在のページをCSV匯出",
LangDE: "Aktuellen Tab als CSV exportieren",
},
"btn.about": {
LangZHTW: "關於", LangEN: "About", LangJA: "詳しく", LangDE: "Über",
},
"loading": {
LangZHTW: "資料載入中...", LangEN: "Loading...", LangJA: "読み込み中...", LangDE: "Daten werden geladen...",
},
"col.name": {
LangZHTW: "名稱 (Name)", LangEN: "Name", LangJA: "名前", LangDE: "Name",
},
"col.status": {
LangZHTW: "狀態/版本 (Status/Ver)", LangEN: "Status/Ver", LangJA: "状態/版", LangDE: "Status/Ver",
},
"col.detail": {
LangZHTW: "詳細資訊 (Details)", LangEN: "Details", LangJA: "詳細情報", LangDE: "Details",
},
"about.title": {
LangZHTW: "關於程式", LangEN: "About App", LangJA: "アプリについて", LangDE: "Über die App",
},
"about.body": {
LangZHTW: "作者: Pecezen.org\n版權所有 © 2026\n\n免責聲明:\n作者不對因使用本程式所造成的任何資料遺失、損壞或其他後果負責。",
LangEN: "Author: Pecezen.org\nCopyright © 2026\n\nDisclaimer:\nThe author is not responsible for any data loss, damage, or other consequences caused by the use of this program.",
LangJA: "作者: Pecezen.org\n著作權 © 2026\n\n免責事項:\n作者は、本プログラムの使用によって生じたデータの紛失、破損、またはその他の結果について一切の責任を負いません。",
LangDE: "Autor: Pecezen.org\nUrheberrecht © 2026\n\nHaftungsausschluss:\nDer Autor haftet nicht für Datenverlust, Schäden oder andere Folgen, die durch die Verwendung dieses Programms entstehen.",
},
}
return table[key][i.lang]
}
/*
=========================
Custom UI Components
=========================
*/
type fixedWidthLabel struct {
widget.Label
width float32
}
func newFixedWidthLabel(text string, width float32) *fixedWidthLabel {
l := &fixedWidthLabel{width: width}
l.ExtendBaseWidget(l)
l.SetText(text)
l.TextStyle = fyne.TextStyle{Bold: true}
return l
}
func (f *fixedWidthLabel) MinSize() fyne.Size { return fyne.NewSize(f.width, 32) }
/*
=========================
PowerShell Data Logic
=========================
*/
func runCmd(psCmd string) string {
cmd := exec.Command("powershell", "-NoProfile", "-Command", "[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;"+psCmd)
cmd.SysProcAttr = &syscall.SysProcAttr{
HideWindow: true,
CreationFlags: 0x08000000,
}
var out bytes.Buffer
cmd.Stdout = &out
_ = cmd.Run()
return strings.TrimSpace(out.String())
}
func collectHardwareInfo() string {
ps := `
$cpu = (Get-CimInstance Win32_Processor).Name;
$cs = Get-CimInstance Win32_ComputerSystem;
$mem = $cs.TotalPhysicalMemory;
Write-Host "CPU: $cpu";
Write-Host "Total Memory: $([math]::Round($mem/1GB, 2)) GB";
Write-Host "Manufacturer: $($cs.Manufacturer)";
Write-Host "Model: $($cs.Model)";
Write-Host "---------------------------------------------------------------------------";
Write-Host "Disk Partition Info (硬碟分區資訊):";
Get-CimInstance Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3} | ForEach-Object {
$size = [math]::Round($_.Size/1GB, 2); $free = [math]::Round($_.FreeSpace/1GB, 2); $used = $size - $free; $per = [math]::Round(($used/$size)*100, 2);
Write-Host "Drive $($_.DeviceID) | Total: $($size)GB | Free: $($free)GB | Used: $($per)%"
} | Out-String`
return runCmd(ps)
}
func collectAntivirusInfo() string {
ps := `
Write-Host "[ 安裝的防毒軟體清單 ]";
$avList = Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct;
if ($avList) { $avList | ForEach-Object { Write-Host "- 軟體名稱: $($_.displayName)" } } else { Write-Host "- 未偵測到第三方防毒軟體" }
Write-Host ""; Write-Host "[ Windows Defender 狀態 ]";
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, AntivirusSignatureVersion, AntivirusSignatureLastUpdated | Format-List | Out-String`
return runCmd(ps)
}
func collectListData(psCmd string) [][]string {
raw := runCmd(psCmd + " | ConvertTo-Csv -NoTypeInformation")
r := csv.NewReader(strings.NewReader(raw))
records, err := r.ReadAll()
if err != nil || len(records) <= 1 {
return [][]string{}
}
return records[1:]
}
/*
=========================
Main Application
=========================
*/
func main() {
a := app.NewWithID("org.pecezen.audit.tool")
a.Settings().SetTheme(&readableTheme{})
savedLang := a.Preferences().StringWithFallback(prefLangKey, "繁體中文")
i := i18n{lang: langMap[savedLang]}
w := a.NewWindow(i.tr("app.title"))
if resourceIconPng != nil {
w.SetIcon(resourceIconPng)
}
w.Resize(fyne.NewSize(1100, 560))
appData := [][]string{}
svcData := [][]string{}
var currentTabIndex int = 0
const nameColWidth float32 = 780
const statusColWidth float32 = 250
createTextTab := func() (*widget.Entry, fyne.CanvasObject, *fixedWidthLabel) {
e := widget.NewMultiLineEntry()
e.Disable()
e.TextStyle = fyne.TextStyle{Monospace: true}
headerLabel := newFixedWidthLabel(i.tr("col.detail"), nameColWidth+statusColWidth)
return e, container.NewBorder(container.NewHBox(headerLabel), nil, nil, nil, container.NewScroll(e)), headerLabel
}
createTableTab := func(data *[][]string) (fyne.CanvasObject, *widget.Table, *fixedWidthLabel, *fixedWidthLabel) {
h1 := newFixedWidthLabel(i.tr("col.name"), nameColWidth)
h2 := newFixedWidthLabel(i.tr("col.status"), statusColWidth)
t := widget.NewTable(
func() (int, int) { return len(*data), 2 },
func() fyne.CanvasObject { l := widget.NewLabel(""); l.Truncation = fyne.TextTruncateEllipsis; return l },
func(id widget.TableCellID, o fyne.CanvasObject) {
if id.Row < len(*data) {
o.(*widget.Label).SetText((*data)[id.Row][id.Col])
}
},
)
t.SetColumnWidth(0, nameColWidth)
t.SetColumnWidth(1, statusColWidth)
return container.NewBorder(container.NewHBox(h1, h2), nil, nil, nil, t), t, h1, h2
}
entryHW, uiHW, lblHW := createTextTab()
entryOS, uiOS, lblOS := createTextTab()
entryAV, uiAV, lblAV := createTextTab()
entryFW, uiFW, lblFW := createTextTab()
entryPol, uiPol, lblPol := createTextTab()
uiApps, tableApps, appH1, appH2 := createTableTab(&appData)
uiSvc, tableSvc, svcH1, svcH2 := createTableTab(&svcData)
tabs := container.NewAppTabs(
container.NewTabItem(i.tr("tab.hardware"), uiHW),
container.NewTabItem(i.tr("tab.os"), uiOS),
container.NewTabItem(i.tr("tab.apps"), uiApps),
container.NewTabItem(i.tr("tab.av"), uiAV),
container.NewTabItem(i.tr("tab.firewall"), uiFW),
container.NewTabItem(i.tr("tab.service"), uiSvc),
container.NewTabItem(i.tr("tab.policy"), uiPol),
)
tabs.OnSelected = func(ti *container.TabItem) {
for idx, item := range tabs.Items {
if item == ti {
currentTabIndex = idx
break
}
}
}
refresh := func() {
p := dialog.NewProgressInfinite(i.tr("app.title"), i.tr("loading"), w)
p.Show()
go func() {
sHW := collectHardwareInfo()
sOS := runCmd("Get-ComputerInfo | Select-Object OsName, OsVersion, OsArchitecture, WindowsVersion, OsInstallDate | Format-List | Out-String")
sAV := collectAntivirusInfo()
sFW := runCmd("Get-NetFirewallProfile | Select-Object Name, Enabled | Out-String")
sPol := runCmd("net accounts")
appData = collectListData(`Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object {$_.DisplayName} | Select-Object DisplayName, DisplayVersion`)
svcData = collectListData("Get-Service | Where-Object {$_.Status -eq 'Running'} | Select-Object DisplayName, Status")
fyne.Do(func() {
entryHW.SetText(sHW)
entryOS.SetText(sOS)
entryAV.SetText(sAV)
entryFW.SetText(sFW)
entryPol.SetText(sPol)
lblHW.SetText(i.tr("col.detail"))
lblOS.SetText(i.tr("col.detail"))
lblAV.SetText(i.tr("col.detail"))
lblFW.SetText(i.tr("col.detail"))
lblPol.SetText(i.tr("col.detail"))
appH1.SetText(i.tr("col.name"))
appH2.SetText(i.tr("col.status"))
svcH1.SetText(i.tr("col.name"))
svcH2.SetText(i.tr("col.status"))
tableApps.Refresh()
tableSvc.Refresh()
p.Hide()
})
}()
}
exportBtn := widget.NewButton(i.tr("btn.export"), func() {
save := dialog.NewFileSave(func(uc fyne.URIWriteCloser, err error) {
if uc == nil {
return
}
defer uc.Close()
var buf bytes.Buffer
buf.Write([]byte{0xEF, 0xBB, 0xBF})
writer := csv.NewWriter(&buf)
switch currentTabIndex {
case 0:
writer.Write([]string{"Hardware Info"})
writer.Write([]string{entryHW.Text})
case 1:
writer.Write([]string{"OS Info"})
writer.Write([]string{entryOS.Text})
case 2:
writer.Write([]string{"Software Name", "Version"})
writer.WriteAll(appData)
case 3:
writer.Write([]string{"Antivirus Status"})
writer.Write([]string{entryAV.Text})
case 4:
writer.Write([]string{"Firewall Status"})
writer.Write([]string{entryFW.Text})
case 5:
writer.Write([]string{"Service Name", "Status"})
writer.WriteAll(svcData)
case 6:
writer.Write([]string{"Security Policy"})
writer.Write([]string{entryPol.Text})
}
writer.Flush()
uc.Write(buf.Bytes())
}, w)
tabNames := []string{"Hardware", "OS", "Software", "Antivirus", "Firewall", "Services", "Policies"}
save.SetFileName("Audit_" + tabNames[currentTabIndex] + ".csv")
save.Show()
})
aboutBtn := widget.NewButton(i.tr("btn.about"), func() {
dialog.ShowInformation(i.tr("about.title"), i.tr("about.body"), w)
})
langSelect := widget.NewSelect(langOptions, func(s string) {
a.Preferences().SetString(prefLangKey, s)
i.lang = langMap[s]
w.SetTitle(i.tr("app.title"))
exportBtn.SetText(i.tr("btn.export"))
aboutBtn.SetText(i.tr("btn.about"))
for idx, key := range []string{"tab.hardware", "tab.os", "tab.apps", "tab.av", "tab.firewall", "tab.service", "tab.policy"} {
tabs.Items[idx].Text = " " + i.tr(key) + " "
}
tabs.Refresh()
refresh()
})
langSelect.SetSelected(savedLang)
controls := container.NewHBox(widget.NewLabel("Lang:"), langSelect, exportBtn, aboutBtn)
w.SetContent(container.NewBorder(container.NewVBox(controls), nil, nil, nil, tabs))
w.ShowAndRun()
}
⚠️ Disclaimer
The author is not responsible for any data loss, damage, or other consequences resulting from the use of this program.
To protect your privacy and security, PeceZen’s tools are built with a simple promise: no tracking, no ads, and fully offline.
If these tools have saved you valuable time, you’re welcome to buy me a cup of coffee and help me keep the servers running and the tools up to date.
[ ☕ Buy me a coffee ]




