动态创建 DSC 配置
Create DSC Configuration dynamically
TLDR;动态创建 DSC 配置文件的最佳方法是什么?
我的任务是维护一个复杂的文件夹结构,包括权限。目前这是通过自定义 PowerShell 模块完成的。对文件夹结构本身进行更改时会出现问题。
使用 DSC 可以消除合规性方面的问题。手动为 20k 文件夹生成 DSC 配置是绝对不可能的。我想通过 PowerShell 从一些输入创建 DSC 配置。这样,可以及时引入更改,并在审核 DSC 配置后应用更改。
还是我完全走错了路,我只能从 DSC 配置中的输入生成结构?
当您编写 DSC 配置时,它是一个脚本,在设计时执行以最终生成 MOF 文件。所以你可以这样做:
Configuration Folders {
Get-Content 'myfolderlist.txt' | ForEach-Object {
File $($_ -replace '\','_')
{
DestinationPath = $_
Ensure = "Present"
}
}
}
这没有解决权限问题,但它展示了如何在 DSC 配置中使用循环。这里要记住的重要一点是,这将在设计时生成一个包含 20k File
资源的静态配置 (MOF) 文件。当 DSC 为 运行ning.
时,循环没有得到 运行(也根本不存在)
DSC 不是最快的。对 20,000 个资源执行 test/set 可能真的很慢,而且有点占用资源。我觉得这可能不是这项工作的工具。
或者,您可以创建一个自定义 DSC 资源来执行测试和设置文件夹结构和权限的所有逻辑,这样它就全部发生在一个资源中。
从本质上讲,这是一个美化的计划任务,但这可能没问题,尤其是如果您想在更广泛的意义上使用 DSC。如果您想看一看,有很多关于如何创建自定义资源的文章(和书籍)。
它不是很漂亮,但我为 NTFS 权限做了类似下面的事情,如果你没有设置子文件夹访问等,你可能需要扩展。我没有看到动态创建配置的简单方法所以我使用不同的参数集重新调整用途。显然,这是 5 年后的事了,所以您可能想出了一些办法。顶部的开关基本上用于替换节点定义文件中的变量。
Function NtfsPermissions
{
Param (
[Parameter(Mandatory=$true)]
[ValidateSet("Present","Absent")]
[string]$Ensure,
[Parameter(Mandatory=$true)]
[string]$Account,
[Parameter(Mandatory=$true)]
[string]$Path,
[string[]]$FileSystemRights,
[string]$Inheritance,
[string]$Depends
)
#Switches are used to dynamically replace accounts and paths that can't be set in nodedefinition file
switch ($Account)
{
"SQLAGENT"
{
$Account = $Node.gSqlAgt
break
}
"SQLSVC"
{
$Account = $Node.gSqlSvc
break
}
"SQLIS"
{
$Account = $Node.gSqlIs
break
}
}
switch ($Path)
{
"AuditPath"
{
$Path = $Node.AuditPath
break
}
"LogDir"
{
$Path = $Node.LogDir
break
}
"DataDir"
{
$Path = $Node.DataDir
break
}
"TempdbDir"
{
$Path = $Node.TempdbDir
break
}
}
if ($Ensure -ne "Absent")
{
cNtfsPermissionEntry $($Account + $Path.Replace(':','_'))
{
Ensure = $Ensure
Path = $Path
Principal = $Account
AccessControlInformation = @(
cNtfsAccessControlInformation
{
AccessControlType = 'Allow'
FileSystemRights = $FileSystemRights
Inheritance = $Inheritance
NoPropagateInherit = $false
}
)
DependsOn = $("[File]$Depends")
}
}
else
{
cNtfsPermissionEntry $($Account + $Path.Replace(':','_'))
{
Ensure = $Ensure
Path = $Path
Principal = $Account
#Need depends on, just not sure how to structure yet
DependsOn = "[File]" + $Depends
}
}
}
$NtfsEntries = $ConfigurationData.NonNodeData.Roles.($Node.Role[0]).NtfsPerms #Need to find a better approach to reference Role
foreach ($ntfs in $NtfsEntries) {
NtfsPermissions -Ensure $ntfs[0] -Account $ntfs[1] -Path $ntfs[2] -FileSystemRights $ntfs[3] -Inheritance $ntfs[4] -Depends $ntfs[5]
}
TLDR;动态创建 DSC 配置文件的最佳方法是什么?
我的任务是维护一个复杂的文件夹结构,包括权限。目前这是通过自定义 PowerShell 模块完成的。对文件夹结构本身进行更改时会出现问题。
使用 DSC 可以消除合规性方面的问题。手动为 20k 文件夹生成 DSC 配置是绝对不可能的。我想通过 PowerShell 从一些输入创建 DSC 配置。这样,可以及时引入更改,并在审核 DSC 配置后应用更改。
还是我完全走错了路,我只能从 DSC 配置中的输入生成结构?
当您编写 DSC 配置时,它是一个脚本,在设计时执行以最终生成 MOF 文件。所以你可以这样做:
Configuration Folders {
Get-Content 'myfolderlist.txt' | ForEach-Object {
File $($_ -replace '\','_')
{
DestinationPath = $_
Ensure = "Present"
}
}
}
这没有解决权限问题,但它展示了如何在 DSC 配置中使用循环。这里要记住的重要一点是,这将在设计时生成一个包含 20k File
资源的静态配置 (MOF) 文件。当 DSC 为 运行ning.
DSC 不是最快的。对 20,000 个资源执行 test/set 可能真的很慢,而且有点占用资源。我觉得这可能不是这项工作的工具。
或者,您可以创建一个自定义 DSC 资源来执行测试和设置文件夹结构和权限的所有逻辑,这样它就全部发生在一个资源中。
从本质上讲,这是一个美化的计划任务,但这可能没问题,尤其是如果您想在更广泛的意义上使用 DSC。如果您想看一看,有很多关于如何创建自定义资源的文章(和书籍)。
它不是很漂亮,但我为 NTFS 权限做了类似下面的事情,如果你没有设置子文件夹访问等,你可能需要扩展。我没有看到动态创建配置的简单方法所以我使用不同的参数集重新调整用途。显然,这是 5 年后的事了,所以您可能想出了一些办法。顶部的开关基本上用于替换节点定义文件中的变量。
Function NtfsPermissions
{
Param (
[Parameter(Mandatory=$true)]
[ValidateSet("Present","Absent")]
[string]$Ensure,
[Parameter(Mandatory=$true)]
[string]$Account,
[Parameter(Mandatory=$true)]
[string]$Path,
[string[]]$FileSystemRights,
[string]$Inheritance,
[string]$Depends
)
#Switches are used to dynamically replace accounts and paths that can't be set in nodedefinition file
switch ($Account)
{
"SQLAGENT"
{
$Account = $Node.gSqlAgt
break
}
"SQLSVC"
{
$Account = $Node.gSqlSvc
break
}
"SQLIS"
{
$Account = $Node.gSqlIs
break
}
}
switch ($Path)
{
"AuditPath"
{
$Path = $Node.AuditPath
break
}
"LogDir"
{
$Path = $Node.LogDir
break
}
"DataDir"
{
$Path = $Node.DataDir
break
}
"TempdbDir"
{
$Path = $Node.TempdbDir
break
}
}
if ($Ensure -ne "Absent")
{
cNtfsPermissionEntry $($Account + $Path.Replace(':','_'))
{
Ensure = $Ensure
Path = $Path
Principal = $Account
AccessControlInformation = @(
cNtfsAccessControlInformation
{
AccessControlType = 'Allow'
FileSystemRights = $FileSystemRights
Inheritance = $Inheritance
NoPropagateInherit = $false
}
)
DependsOn = $("[File]$Depends")
}
}
else
{
cNtfsPermissionEntry $($Account + $Path.Replace(':','_'))
{
Ensure = $Ensure
Path = $Path
Principal = $Account
#Need depends on, just not sure how to structure yet
DependsOn = "[File]" + $Depends
}
}
}
$NtfsEntries = $ConfigurationData.NonNodeData.Roles.($Node.Role[0]).NtfsPerms #Need to find a better approach to reference Role
foreach ($ntfs in $NtfsEntries) {
NtfsPermissions -Ensure $ntfs[0] -Account $ntfs[1] -Path $ntfs[2] -FileSystemRights $ntfs[3] -Inheritance $ntfs[4] -Depends $ntfs[5]
}