首页 > 解决方案 > 使用 PS 脚本导出和导入包含 CSV 文件的文件夹结构和绑定

问题描述

我是 ps 脚本的新手,正在寻找一些建议。

我们每隔几年更换一次数据共享服务器,手动创建完整的文件夹结构和权限非常繁琐,所以我尝试使用 powershell 脚本将其自动化。因为我是新手,所以我一直在谷歌上搜索一些示例和片段,并一直在编译我需要的东西。

我的导出脚本读取文件夹结构并将其写入文本文件,一旦我将文件夹移动到新服务器,我的导入脚本就会创建它,没问题。问题在于访问权限。它读取权限并将其写入 CSV,但是一旦我尝试导入它,就会出现错误:

新对象:无法将参数“2”,值为“TRUE”,用于“FileSystemAccessRule”以键入“System.Security.AccessControl.AccessControlType”:“无法将值“TRUE”转换为“System.Security.AccessControl”。 AccessControlType”。错误:“无法将标识符名称 TRUE 与有效的枚举器名称匹配。指定以下枚举器名称之一并重试:Allow, Deny"" At line:1 char:23

  • ... ccessRule = 新对象 System.Security.AccessControl.FileSystemAccess ...

  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
    • FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

据我了解,它正在寻找允许/拒绝而不是真/假,但导出给出的是真/假。所以我猜我的出口有问题......

这是我的代码,如果有人能指出我正确的方向,我将不胜感激!(让我知道我是否应该发布所有代码,我只是不想比我已经做的更混乱:D)

出口:

$FolderPath = dir -Directory -Path $DriveLetter -Force
$Report = @()
Foreach ($Folder in $FolderPath)
    {
        if ($Folder.Name -notlike '*$RECYCLE.BIN*')
        {
            
            if ($Folder.Name -notlike '*System Volume Information*')
            {          
                $Acl = Get-Acl -Path $Folder.FullName
                foreach ($Access in $acl.Access)
                {                        
                    $Properties = [ordered]@{'FolderName'=$Folder.Name;'IDRef'=$Access.IdentityReference;'FSRights'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
                    $Report += New-Object -TypeName PSObject -Property $Properties                            
                }
            }
            
        }
            
    }
$Report | Export-Csv -path $ExportACL -NoTypeInformation

进口:

foreach ( $LItem in $ACL_Imp ) 
    {        
        $path_full = $Drivepath.ToString() + $LItem.FolderName
        $ACL_Set = Get-Acl $path_full
        $permission = $LItem.IDRef, $LItem.FSRights, $LItem.Inherited
        $accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission <<<--- Error occurs here
        $ACL_Set.SetAccessRule($accessRule)        
        $ACL_Set | Set-Acl $path_full
    }

导出 csv 中一位用户的示例(我删除了驱动器号,因为它始终不是相同的驱动器号。)

#TYPE System.Management.Automation.PSCustomObject;;; 文件夹名称;IDRef;FSRights;继承的 Data\UserA;域\UserA;FullControl;FALSE Data\UserA;NT AUTHORITY\SYSTEM;FullControl;TRUE Data\UserA;DOMAIN\UserB;FullControl;TRUE Data\UserA;BUILTIN\Administrators;FullControl ;TRUE Data\UserA;DOMAIN\GRP_A;ReadAndExecute, 同步;TRUE Data\UserA;Domain\GRP_A;ReadAndExecute, 同步;TRUE

再次提前感谢您的任何帮助!如果你不能提供任何东西,谢谢你花时间检查一下!!:)

标签: powershellcsvimportexportadmin-rights

解决方案


我已经更改了导出和导入的变量数量,这似乎起到了作用。(导出所有变量,仅使用 5 个)

我发布我的完整代码以防其他人也想使用它,或者想根据他们的需要进行修改:)

希望这将对将来的某人有所帮助,并且我的评论是有道理的..

Our Directory structure:
ImportExport <-- Location of scripts and output files (whole folder to be copied to new server)
Shared
Software
Users/UserA/
Users/UserB/
....
Users/UserZ/

出口:

#Variables
$drivepath = Get-Location                                                        #Get working drives' letter
$DriveLetter = Split-Path -qualifier $drivepath
$ExportACL = $DriveLetter.ToString() + "\ImportExport\export_acl.csv"            #ACL Location
$ExportFolders = $DriveLetter.ToString() + "\ImportExport\export_folders.txt"    #File with List of Folders
$UsersPath = $DriveLetter.ToString() + "\Users"                                  #"Users" folders location on working drive located in Data folder

#Read user access levels on each folder on working drive and write to file.
cd.. #<-- add this if script is not run from within the PS environment.
$FolderPath = dir -Directory -Path $DriveLetter -Force
$Report = @()
Foreach ($Folder in $FolderPath)
    {
        if ($Folder.Name -notlike '*$RECYCLE.BIN*')
        {
            if ($Folder.Name -notlike '*ImportExport*')
            {
                if ($Folder.Name -notlike '*System Volume Information*')
                {          
                    $Acl = Get-Acl -Path $Folder.FullName
                    foreach ($Access in $acl.Access)
                    {                        
                        $Properties = [ordered]@{'FolderName'=$Folder.Name;'FSRights'=$Access.FileSystemRights;'ACType'=$Access.AccessControlType;'IDRef'=$Access.IdentityReference;'Inherited'=$Access.IsInherited;'IFlags'=$Access.InheritanceFlags;'PFlags'=$Access.PropagationFlags}
                        $Report += New-Object -TypeName PSObject -Property $Properties                            
                    }
                }
            }
        }            
    }
$Report | Export-Csv -path $ExportACL -NoTypeInformation

#Read user access levels on each child folder of Users folders on working drive and add to file.
$FolderPath = dir -Directory -Path $UsersPath -Force
$UserReport = @()
Foreach ($Folder in $FolderPath)
    {
        if ($Folder.Name -notlike '*$RECYCLE.BIN*')
        {
            if ($Folder.Name -notlike '*ImportExport*')
            {
                if ($Folder.Name -notlike '*System Volume Information*')
                {          
                    $Acl = Get-Acl -Path $Folder.FullName
                    foreach ($Access in $acl.Access)
                    {   
                        $StrFolderPath = $Folder.Parent.ToString() + "\" + $Folder.BaseName
                            
                        $Properties = [ordered]@{'FolderName'=$StrFolderPath;'FSRights'=$Access.FileSystemRights;'ACType'=$Access.AccessControlType;'IDRef'=$Access.IdentityReference;'Inherited'=$Access.IsInherited;'IFlags'=$Access.InheritanceFlags;'PFlags'=$Access.PropagationFlags}
                        $UserReport += New-Object -TypeName PSObject -Property $Properties                                                                                    
                    }
                }
            }
        }            
    }
$UserReport | Export-Csv -append $ExportACL


#Read Directory Structure and Export to File
$Dirs = Dir -Directory -Path $DriveLetter -Force
foreach($Dir in $Dirs)
    {
        if ($Dir.Name -notlike '*$RECYCLE.BIN*')
        {
            if ($Dir.Name -notlike '*ImportExport*')
            {
                if ($Dir.Name -notlike '*System Volume Information*')
                {          
                    $Dir.Name | out-file -Append $ExportFolders
                }
            }
        }
    }
$Dirs = Get-ChildItem -Path $UsersPath -Force
foreach($Dir in $Dirs)
    {
        $DirName = "Users\" + $Dir.Name
        $DirName | out-file -Append $ExportFolders
    }

在导入之前,我在 excel 中打开 csv 文件并将其设置为不同的列,所以我使用“;” 作为分隔符,如果我不编辑它,我会很挣扎。具有多个值的变量用“,”分隔,这会弄乱导入。

此外,由于管理员权限需要应用 ACL,脚本需要在提升的 PS 环境中运行,无法弄清楚如何在外部执行。可能可以运行一个批处理文件来执行 RunAs,但我暂时受够了这个脚本。:p

进口:

#Variables
$drivepath = Get-Location                                                        #Get working drives' letter
$DriveLetter = Split-Path -qualifier $drivepath                                  
$ImportACL = $DriveLetter.ToString() + "\ImportExport\export_acl.csv"            #ACL Location
$ACL_Imp = Import-Csv $ImportACL -Delimiter ';'                                  #Import ACL
$ImportFolders = $DriveLetter.ToString() + "\ImportExport\export_folders.txt"    #File with List of Folders
$UsersPath = $DriveLetter.ToString() + "\Users"                                  #Users' folder location on working drive

#Create Folders from text file.
Get-Content $ImportFolders | %{mkdir "$DriveLetter\$_"}

#Apply ACL to created Folder structure
foreach ( $LItem in $ACL_Imp ) 
    {
        $path_full = $Drivepath.ToString() + $LItem.FolderName
        $ACL_Set = Get-Acl $path_full
        
             
        $permission = $LItem.IDRef, $LItem.FSRights, $LItem.IFlags, $LItem.PFlags, $LItem.ACType       
                    
        $accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission
       
        $ACL_Set.SetAccessRule($accessRule)
        
        $ACL_Set | Set-Acl $path_full
    }

推荐阅读