Python 扫描 ICACL
Python Scan for ICACL
我正在努力解决我公司目前遇到的一个问题,我们有一个非常大的共享驱动器,已经有 20 多年的历史了。这些文件夹中有很多安全组以及不再存在并显示为乱码文本的个人用户。
我们想扫描整个目录并将所有权限输出到一个 excel 文件。
我想出了这个解决方案,但是,我认为我没有像我认为的那样有效地完成它。
这是整个脚本:
import os
import subprocess
import xlsxwriter
import win32com.client as win32
# *** IMPORTANT ****
# MUST INSTALL XLSXWRITER AND PYWIN32 IN VENV
# PIP INSTALL XLSXWRITER
# PIP INSTALL PYWIN32
def CheckPerms(t, save_dir):
global firstDir
# LOOP THROUGH ALL PATHS IN ROOT DIRECTORY
for path in os.listdir(t):
# VARIABLE HOLDS FULL PATH OF THE ROOT DIRECTORY
full_root_path = os.path.join(t, path)
# CHECKS IF PATH IS A FILE, IF IT IS A FILE, SKIP AND CONTINUE WITH SCAN
if not os.path.isfile(full_root_path):
# VARIABLE HOLDS ROOT NAME OF FULL ROOT PATH
# EXAMPLE: INPUT - C:\TEST, RETURNS - C:\
firstDir = os.path.split(full_root_path)
# PRINTS CURRENT DIRECTORY THAT IS BEING SCANNED
print("Working on: " + firstDir[1])
# PREPARE EXCEL WORKBOOK IN SPECIFIED LOCATION
# SAVES AS NAME OF DIR BEING SCANNED
workbook = xlsxwriter.Workbook(f'{save_dir}\{firstDir[1]}.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write("A1", "Directory Path")
worksheet.write("B1", "Security Groups")
row = 1
col = 0
# LOOP THOUGH A WALK OF EACH ROOT PATH
# THIS WILL SCAN FRONT TO BACK, TOP TO BOTTOM OF THE ENTIRE TREE
for r, d, f in os.walk(full_root_path):
# CAPTURE THE OUTPUT OF THE SYSTEM CMD ICALCS COMMAND ON DIRECTORY BEING SCANNED
sub_return = subprocess.check_output(["icacls", r])
try:
# TRY TO DECODE OUTPUT AS UTF-8
sub_return = sub_return.decode('utf-8')
except:
# SOMETIMES CANNOT DECODE, THIS WILL CATCH ERROR AND CONTINUE
print("Decode Error: Skipping a line")
continue
# SPLIT THE LINES OF THE RETURNED STRING
split_icacl_lines = sub_return.splitlines()
# ICACLS RETURNS A STATUS LINE AFTER COMPLETE
# THIS WILL REMOVE THE LAST LINE, EXAMPLE:
# "Successfully processed 1 files; Failed processing 0 files"
del split_icacl_lines[-1:]
# FIRST LINE OF ICACLS INCLUDES THE DIRECTORY AS WELL AS FIRST LINE OF ICACLS
# THIS WILL REVERSE SPLIT BY FIRST EMPTY SPACE TO SEPARATE THE LINES
# AND DELETE IT FROM THE ORIGINAL LIST
firstLine = split_icacl_lines[0].rsplit(" ", 1)
del split_icacl_lines[0]
# THERE HAPPENS TO BE AN EMPTY LINE, SO WE REMOVE IT HERE
del split_icacl_lines[-1:]
# ADD THE FIRST ELEMENT OF THE FIRST LINE BACK INTO THE BEGINNING OF THE LIST
split_icacl_lines.insert(0, firstLine[0].lstrip())
# APPEND THE SECOND ELEMENT OF THE FIRST LINE TO END OF LIST
split_icacl_lines.append(firstLine[1].lstrip())
# FIRST ELEMENT OF LIST IS THE TARGET DIRECTORY
target_directory = split_icacl_lines[0]
# DELETE TARGET DIRECTORY FROM LIST
del split_icacl_lines[0]
# ADD TARGET DIRECTORY TO EXCEL FILE
worksheet.write(row, col, target_directory)
# MOVE OVER EXCEL COLUMN BY 1
col += 1
# LOOP THROUGH EACH LINE IN THE FINAL ICACL DATA AND
# OUTPUT IT TO EXCEL FILE NEXT TO THE DIRECTORY IT
# BELONGS TO
for lines in split_icacl_lines:
# STRIP LINES OF ALL ABNORMAL CHARACTERS
output = lines.lstrip()
# INSERT LINE INTO WORKBOOK
worksheet.write(row, col, output)
row += 1
# EMPTY LINE BETWEEN EACH SCAN OUTPUT
row += 1
# RESET COLUMN TO 0
col = 0
# CLOSE WORKBOOK, SAVING IT
workbook.close()
# OPEN WORKBOOK IN WIN32, AUTO-FIT EACH COLUMN AND SAVE IT
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(f'C:\Test\{firstDir[1]}.xlsx')
ws = wb.Worksheets("Sheet1")
ws.Columns.AutoFit()
wb.Save()
excel.Application.Quit()
# REPEAT ALL ABOVE FOR EACH DIRECTORY
CheckPerms("C:\", "C:\Test")
我遇到的问题是,当 ICACLS 在 windows 中是 运行 时,它的第一行 returns 包括目录以及第一个权限,例如:
C:\Users\Michael>icacls C:\
C:\ BUILTIN\Administrators:(OI)(CI)(F)
NT AUTHORITY\SYSTEM:(OI)(CI)(F)
BUILTIN\Users:(OI)(CI)(RX)
NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(M)
NT AUTHORITY\Authenticated Users:(AD)
Mandatory Label\High Mandatory Level:(OI)(NP)(IO)(NW)
这就是为什么我必须在将输出拆分为列表后对输出做一些奇怪的事情。
拆分原始输出后,我将该输出的第一行拆分为空 space 并将每个元素添加回列表中,但是,对于目录“Program Files”中的某些文件我得到这样奇怪的输出:
Image of excel output file
任何人都可以建议更好的方法吗?
非常感谢。
评论太长了。消除第一行的所有复杂操作(请参阅以下代码片段中的 ##
注释)并尝试它是否有效。
主要看下面几行:
split_icacl_lines[0] = split_icacl_lines[0].replace( r, '', 1)
target_directory = r
代码:
# LOOP THOUGH A WALK OF EACH ROOT PATH
# THIS WILL SCAN FRONT TO BACK, TOP TO BOTTOM OF THE ENTIRE TREE
for r, d, f in os.walk(full_root_path):
# CAPTURE THE OUTPUT OF THE SYSTEM CMD ICALCS COMMAND ON DIRECTORY BEING SCANNED
sub_return = subprocess.check_output(["icacls", r])
try:
# TRY TO DECODE OUTPUT AS UTF-8
sub_return = sub_return.decode('utf-8')
except:
# SOMETIMES CANNOT DECODE, THIS WILL CATCH ERROR AND CONTINUE
print("Decode Error: Skipping a line")
continue
# SPLIT THE LINES OF THE RETURNED STRING
split_icacl_lines = sub_return.splitlines()
# ICACLS RETURNS A STATUS LINE AFTER COMPLETE
# THIS WILL REMOVE THE LAST LINE, EXAMPLE:
# "Successfully processed 1 files; Failed processing 0 files"
del split_icacl_lines[-1:]
# FIRST LINE OF ICACLS INCLUDES THE DIRECTORY AS WELL AS FIRST LINE OF ICACLS
# THIS WILL REVERSE SPLIT BY FIRST EMPTY SPACE TO SEPARATE THE LINES
# AND DELETE IT FROM THE ORIGINAL LIST
## firstLine = split_icacl_lines[0].rsplit(" ", 1)
## del split_icacl_lines[0]
split_icacl_lines[0] = split_icacl_lines[0].replace( r, '', 1)
# THERE HAPPENS TO BE AN EMPTY LINE, SO WE REMOVE IT HERE
del split_icacl_lines[-1:]
# ADD THE FIRST ELEMENT OF THE FIRST LINE BACK INTO THE BEGINNING OF THE LIST
## split_icacl_lines.insert(0, firstLine[0].lstrip())
# APPEND THE SECOND ELEMENT OF THE FIRST LINE TO END OF LIST
## split_icacl_lines.append(firstLine[1].lstrip())
# FIRST ELEMENT OF LIST IS THE TARGET DIRECTORY
## target_directory = split_icacl_lines[0]
target_directory = r
# DELETE TARGET DIRECTORY FROM LIST
## del split_icacl_lines[0]
# ADD TARGET DIRECTORY TO EXCEL FILE
worksheet.write(row, col, target_directory)
# MOVE OVER EXCEL COLUMN BY 1
col += 1
# LOOP THROUGH EACH LINE IN THE FINAL ICACL DATA AND
# OUTPUT IT TO EXCEL FILE NEXT TO THE DIRECTORY IT
# BELONGS TO
for lines in split_icacl_lines:
# STRIP LINES OF ALL ABNORMAL CHARACTERS
output = lines.lstrip()
# INSERT LINE INTO WORKBOOK
worksheet.write(row, col, output)
row += 1
# EMPTY LINE BETWEEN EACH SCAN OUTPUT
row += 1
# RESET COLUMN TO 0
col = 0
我正在努力解决我公司目前遇到的一个问题,我们有一个非常大的共享驱动器,已经有 20 多年的历史了。这些文件夹中有很多安全组以及不再存在并显示为乱码文本的个人用户。
我们想扫描整个目录并将所有权限输出到一个 excel 文件。
我想出了这个解决方案,但是,我认为我没有像我认为的那样有效地完成它。
这是整个脚本:
import os
import subprocess
import xlsxwriter
import win32com.client as win32
# *** IMPORTANT ****
# MUST INSTALL XLSXWRITER AND PYWIN32 IN VENV
# PIP INSTALL XLSXWRITER
# PIP INSTALL PYWIN32
def CheckPerms(t, save_dir):
global firstDir
# LOOP THROUGH ALL PATHS IN ROOT DIRECTORY
for path in os.listdir(t):
# VARIABLE HOLDS FULL PATH OF THE ROOT DIRECTORY
full_root_path = os.path.join(t, path)
# CHECKS IF PATH IS A FILE, IF IT IS A FILE, SKIP AND CONTINUE WITH SCAN
if not os.path.isfile(full_root_path):
# VARIABLE HOLDS ROOT NAME OF FULL ROOT PATH
# EXAMPLE: INPUT - C:\TEST, RETURNS - C:\
firstDir = os.path.split(full_root_path)
# PRINTS CURRENT DIRECTORY THAT IS BEING SCANNED
print("Working on: " + firstDir[1])
# PREPARE EXCEL WORKBOOK IN SPECIFIED LOCATION
# SAVES AS NAME OF DIR BEING SCANNED
workbook = xlsxwriter.Workbook(f'{save_dir}\{firstDir[1]}.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write("A1", "Directory Path")
worksheet.write("B1", "Security Groups")
row = 1
col = 0
# LOOP THOUGH A WALK OF EACH ROOT PATH
# THIS WILL SCAN FRONT TO BACK, TOP TO BOTTOM OF THE ENTIRE TREE
for r, d, f in os.walk(full_root_path):
# CAPTURE THE OUTPUT OF THE SYSTEM CMD ICALCS COMMAND ON DIRECTORY BEING SCANNED
sub_return = subprocess.check_output(["icacls", r])
try:
# TRY TO DECODE OUTPUT AS UTF-8
sub_return = sub_return.decode('utf-8')
except:
# SOMETIMES CANNOT DECODE, THIS WILL CATCH ERROR AND CONTINUE
print("Decode Error: Skipping a line")
continue
# SPLIT THE LINES OF THE RETURNED STRING
split_icacl_lines = sub_return.splitlines()
# ICACLS RETURNS A STATUS LINE AFTER COMPLETE
# THIS WILL REMOVE THE LAST LINE, EXAMPLE:
# "Successfully processed 1 files; Failed processing 0 files"
del split_icacl_lines[-1:]
# FIRST LINE OF ICACLS INCLUDES THE DIRECTORY AS WELL AS FIRST LINE OF ICACLS
# THIS WILL REVERSE SPLIT BY FIRST EMPTY SPACE TO SEPARATE THE LINES
# AND DELETE IT FROM THE ORIGINAL LIST
firstLine = split_icacl_lines[0].rsplit(" ", 1)
del split_icacl_lines[0]
# THERE HAPPENS TO BE AN EMPTY LINE, SO WE REMOVE IT HERE
del split_icacl_lines[-1:]
# ADD THE FIRST ELEMENT OF THE FIRST LINE BACK INTO THE BEGINNING OF THE LIST
split_icacl_lines.insert(0, firstLine[0].lstrip())
# APPEND THE SECOND ELEMENT OF THE FIRST LINE TO END OF LIST
split_icacl_lines.append(firstLine[1].lstrip())
# FIRST ELEMENT OF LIST IS THE TARGET DIRECTORY
target_directory = split_icacl_lines[0]
# DELETE TARGET DIRECTORY FROM LIST
del split_icacl_lines[0]
# ADD TARGET DIRECTORY TO EXCEL FILE
worksheet.write(row, col, target_directory)
# MOVE OVER EXCEL COLUMN BY 1
col += 1
# LOOP THROUGH EACH LINE IN THE FINAL ICACL DATA AND
# OUTPUT IT TO EXCEL FILE NEXT TO THE DIRECTORY IT
# BELONGS TO
for lines in split_icacl_lines:
# STRIP LINES OF ALL ABNORMAL CHARACTERS
output = lines.lstrip()
# INSERT LINE INTO WORKBOOK
worksheet.write(row, col, output)
row += 1
# EMPTY LINE BETWEEN EACH SCAN OUTPUT
row += 1
# RESET COLUMN TO 0
col = 0
# CLOSE WORKBOOK, SAVING IT
workbook.close()
# OPEN WORKBOOK IN WIN32, AUTO-FIT EACH COLUMN AND SAVE IT
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(f'C:\Test\{firstDir[1]}.xlsx')
ws = wb.Worksheets("Sheet1")
ws.Columns.AutoFit()
wb.Save()
excel.Application.Quit()
# REPEAT ALL ABOVE FOR EACH DIRECTORY
CheckPerms("C:\", "C:\Test")
我遇到的问题是,当 ICACLS 在 windows 中是 运行 时,它的第一行 returns 包括目录以及第一个权限,例如:
C:\Users\Michael>icacls C:\
C:\ BUILTIN\Administrators:(OI)(CI)(F)
NT AUTHORITY\SYSTEM:(OI)(CI)(F)
BUILTIN\Users:(OI)(CI)(RX)
NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(M)
NT AUTHORITY\Authenticated Users:(AD)
Mandatory Label\High Mandatory Level:(OI)(NP)(IO)(NW)
这就是为什么我必须在将输出拆分为列表后对输出做一些奇怪的事情。
拆分原始输出后,我将该输出的第一行拆分为空 space 并将每个元素添加回列表中,但是,对于目录“Program Files”中的某些文件我得到这样奇怪的输出:
Image of excel output file
任何人都可以建议更好的方法吗?
非常感谢。
评论太长了。消除第一行的所有复杂操作(请参阅以下代码片段中的 ##
注释)并尝试它是否有效。
主要看下面几行:
split_icacl_lines[0] = split_icacl_lines[0].replace( r, '', 1)
target_directory = r
代码:
# LOOP THOUGH A WALK OF EACH ROOT PATH
# THIS WILL SCAN FRONT TO BACK, TOP TO BOTTOM OF THE ENTIRE TREE
for r, d, f in os.walk(full_root_path):
# CAPTURE THE OUTPUT OF THE SYSTEM CMD ICALCS COMMAND ON DIRECTORY BEING SCANNED
sub_return = subprocess.check_output(["icacls", r])
try:
# TRY TO DECODE OUTPUT AS UTF-8
sub_return = sub_return.decode('utf-8')
except:
# SOMETIMES CANNOT DECODE, THIS WILL CATCH ERROR AND CONTINUE
print("Decode Error: Skipping a line")
continue
# SPLIT THE LINES OF THE RETURNED STRING
split_icacl_lines = sub_return.splitlines()
# ICACLS RETURNS A STATUS LINE AFTER COMPLETE
# THIS WILL REMOVE THE LAST LINE, EXAMPLE:
# "Successfully processed 1 files; Failed processing 0 files"
del split_icacl_lines[-1:]
# FIRST LINE OF ICACLS INCLUDES THE DIRECTORY AS WELL AS FIRST LINE OF ICACLS
# THIS WILL REVERSE SPLIT BY FIRST EMPTY SPACE TO SEPARATE THE LINES
# AND DELETE IT FROM THE ORIGINAL LIST
## firstLine = split_icacl_lines[0].rsplit(" ", 1)
## del split_icacl_lines[0]
split_icacl_lines[0] = split_icacl_lines[0].replace( r, '', 1)
# THERE HAPPENS TO BE AN EMPTY LINE, SO WE REMOVE IT HERE
del split_icacl_lines[-1:]
# ADD THE FIRST ELEMENT OF THE FIRST LINE BACK INTO THE BEGINNING OF THE LIST
## split_icacl_lines.insert(0, firstLine[0].lstrip())
# APPEND THE SECOND ELEMENT OF THE FIRST LINE TO END OF LIST
## split_icacl_lines.append(firstLine[1].lstrip())
# FIRST ELEMENT OF LIST IS THE TARGET DIRECTORY
## target_directory = split_icacl_lines[0]
target_directory = r
# DELETE TARGET DIRECTORY FROM LIST
## del split_icacl_lines[0]
# ADD TARGET DIRECTORY TO EXCEL FILE
worksheet.write(row, col, target_directory)
# MOVE OVER EXCEL COLUMN BY 1
col += 1
# LOOP THROUGH EACH LINE IN THE FINAL ICACL DATA AND
# OUTPUT IT TO EXCEL FILE NEXT TO THE DIRECTORY IT
# BELONGS TO
for lines in split_icacl_lines:
# STRIP LINES OF ALL ABNORMAL CHARACTERS
output = lines.lstrip()
# INSERT LINE INTO WORKBOOK
worksheet.write(row, col, output)
row += 1
# EMPTY LINE BETWEEN EACH SCAN OUTPUT
row += 1
# RESET COLUMN TO 0
col = 0