This commit is contained in:
Friedrich Weinmann 2018-10-09 23:20:04 +02:00
Родитель 0ac3bce5b5
Коммит 5217f30c7b
48 изменённых файлов: 4095 добавлений и 342 удалений

2
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

342
.gitignore поставляемый
Просмотреть файл

@ -1,330 +1,22 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# ignore the settings folder and files for VSCode and PSS
.vscode/*
*.psproj
*TempPoint*
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Ignore staging info from Visual Studio
library/PAWTools/.vs/*
library/PAWTools/PAWTools/bin/*
library/PAWTools/PAWTools/obj/*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# ignore PowerShell Studio MetaData
PAWTools/PAWTools.psproj
PAWTools/PAWTools.psproj.bak
PAWTools/PAWTools.psprojs
PAWTools/PAWTools.psproj
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# ignore the TestResults
TestResults/*
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# ignore the publishing Directory
publish/*

34
LICENSE
Просмотреть файл

@ -1,21 +1,21 @@
MIT License
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
Copyright (c) 2018 Friedrich Weinmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

83
PAWTools/PAWTools.psd1 Normal file
Просмотреть файл

@ -0,0 +1,83 @@
@{
# Script module or binary module file associated with this manifest
ModuleToProcess = 'PAWTools.psm1'
# Version number of this module.
ModuleVersion = '1.0.0.0'
# ID used to uniquely identify this module
GUID = 'a5ba9e8f-d1df-41ed-a40e-3f75ad2a62c5'
# Author of this module
Author = 'Friedrich Weinmann'
# Company or vendor of this module
CompanyName = 'Microsoft'
# Copyright statement for this module
Copyright = 'Copyright (c) 2018 Friedrich Weinmann'
# Description of the functionality provided by this module
Description = 'Provides tools that support implementing Privileged Access Workstations in a Active Directory Forest'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Modules that must be imported into the global environment prior to importing
# this module
RequiredModules = @(
@{ ModuleName='PSFramework'; ModuleVersion='0.10.27.128' }
)
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @('bin\PAWTools.dll')
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @('xml\PAWTools.Types.ps1xml')
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @('xml\PAWTools.Format.ps1xml')
# Functions to export from this module
FunctionsToExport = ''
# Cmdlets to export from this module
CmdletsToExport = ''
# Variables to export from this module
VariablesToExport = ''
# Aliases to export from this module
AliasesToExport = ''
# List of all modules packaged with this module
ModuleList = @()
# List of all files packaged with this module
FileList = @()
# Private data to pass to the module specified in ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
#Support for PowerShellGet galleries.
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
} # End of PrivateData hashtable
}

85
PAWTools/PAWTools.psm1 Normal file
Просмотреть файл

@ -0,0 +1,85 @@
$script:ModuleRoot = $PSScriptRoot
$script:ModuleVersion = "1.0.0.0"
# Detect whether at some level dotsourcing was enforced
$script:doDotSource = Get-PSFConfigValue -FullName PAWTools.Import.DoDotSource -Fallback $false
if ($PAWTools_dotsourcemodule) { $script:doDotSource = $true }
<#
Note on Resolve-Path:
All paths are sent through Resolve-Path/Resolve-PSFPath in order to convert them to the correct path separator.
This allows ignoring path separators throughout the import sequence, which could otherwise cause trouble depending on OS.
Resolve-Path can only be used for paths that already exist, Resolve-PSFPath can accept that the last leaf my not exist.
This is important when testing for paths.
#>
# Detect whether at some level loading individual module files, rather than the compiled module was enforced
$importIndividualFiles = Get-PSFConfigValue -FullName PAWTools.Import.IndividualFiles -Fallback $false
if ($PAWTools_importIndividualFiles) { $importIndividualFiles = $true }
if (Test-Path (Resolve-PSFPath -Path "$($script:ModuleRoot)\..\.git" -SingleItem -NewChild)) { $importIndividualFiles = $true }
if (-not (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\commands.ps1" -SingleItem -NewChild))) { $importIndividualFiles = $true }
function Import-ModuleFile
{
<#
.SYNOPSIS
Loads files into the module on module import.
.DESCRIPTION
This helper function is used during module initialization.
It should always be dotsourced itself, in order to proper function.
This provides a central location to react to files being imported, if later desired
.PARAMETER Path
The path to the file to load
.EXAMPLE
PS C:\> . Import-ModuleFile -File $function.FullName
Imports the file stored in $function according to import policy
#>
[CmdletBinding()]
Param (
[string]
$Path
)
if ($doDotSource) { . (Resolve-Path $Path) }
else { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText((Resolve-Path $Path)))), $null, $null) }
}
if ($importIndividualFiles)
{
# Execute Preimport actions
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\preimport.ps1"
# Import all internal functions
foreach ($function in (Get-ChildItem "$ModuleRoot\internal\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
{
. Import-ModuleFile -Path $function.FullName
}
# Import all public functions
foreach ($function in (Get-ChildItem "$ModuleRoot\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
{
. Import-ModuleFile -Path $function.FullName
}
# Execute Postimport actions
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\postimport.ps1"
}
else
{
if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesBefore.ps1" -SingleItem -NewChild))
{
. Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesBefore.ps1"
}
. Import-ModuleFile -Path "$($script:ModuleRoot)\commands.ps1"
if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesAfter.ps1" -SingleItem -NewChild))
{
. Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesAfter.ps1"
}
}

7
PAWTools/bin/readme.md Normal file
Просмотреть файл

@ -0,0 +1,7 @@
# bin folder
The bin folder exists to store binary data. And scripts related to the type system.
This may include your own C#-based library, third party libraries you want to include (watch the license!), or a script declaring type accelerators (effectively aliases for .NET types)
For more information on Type Accelerators, see the help on Set-PSFTypeAlias

Просмотреть файл

@ -0,0 +1,11 @@
TOPIC
about_PAWTools
SHORT DESCRIPTION
Explains how to use the PAWTools powershell module
LONG DESCRIPTION
<Insert Content here>
KEYWORDS
PAWTools

Просмотреть файл

@ -0,0 +1,7 @@
# Functions
This is the folder where the functions go.
Depending on the complexity of the module, it is recommended to subdivide them into subfolders.
The module will pick up all .ps1 files recursively

Просмотреть файл

@ -0,0 +1,15 @@
<#
This is an example configuration file
By default, it is enough to have a single one of them,
however if you have enough configuration settings to justify having multiple copies of it,
feel totally free to split them into multiple files.
#>
<#
# Example Configuration
Set-PSFConfig -Module 'PAWTools' -Name 'Example.Setting' -Value 10 -Initialize -Validation 'integer' -Handler { } -Description "Example configuration setting. Your module can then use the setting using 'Get-PSFConfigValue'"
#>
Set-PSFConfig -Module 'PAWTools' -Name 'Import.DoDotSource' -Value $false -Initialize -Validation 'bool' -Description "Whether the module files should be dotsourced on import. By default, the files of this module are read as string value and invoked, which is faster but worse on debugging."
Set-PSFConfig -Module 'PAWTools' -Name 'Import.IndividualFiles' -Value $false -Initialize -Validation 'bool' -Description "Whether the module files should be imported individually. During the module build, all module code is compiled into few files, which are imported instead by default. Loading the compiled versions is faster, using the individual files is easier for debugging and testing out adjustments."

Просмотреть файл

@ -0,0 +1,14 @@
# Configurations
Through the `PSFramework` you have a simple method that allows you to ...
- Publish settings
- With onboard documentation
- Input validation
- Scripts that run on change of settings
- That can be discovered and updated by the user
- That can be administrated by policy & DSC
The configuration system is a bit too complex to describe in a help file, you can however visit us at http://psframework.org for detailed guidance.
An example can be seen in the attached ps1 file

Просмотреть файл

@ -0,0 +1,7 @@
# Functions
This is the folder where the internal functions go.
Depending on the complexity of the module, it is recommended to subdivide them into subfolders.
The module will pick up all .ps1 files recursively

Просмотреть файл

@ -0,0 +1,21 @@
New-PSFLicense -Product 'PAWTools' -Manufacturer 'Friedrich Weinmann' -ProductVersion $script:ModuleVersion -ProductType Module -Name MIT -Version "1.0.0.0" -Date (Get-Date "2018-10-09") -Text @"
Copyright (c) 2018 Friedrich Weinmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"@

Просмотреть файл

@ -0,0 +1,17 @@
# Add all things you want to run after importing the main code
# Load Configurations
foreach ($file in (Get-ChildItem "$ModuleRoot\internal\configurations\*.ps1" -ErrorAction Ignore)) {
. Import-ModuleFile -Path $file.FullName
}
# Load Tab Expansion
foreach ($file in (Get-ChildItem "$ModuleRoot\internal\tepp\*.tepp.ps1" -ErrorAction Ignore)) {
. Import-ModuleFile -Path $file.FullName
}
# Load Tab Expansion Assignment
. Import-ModuleFile -Path "$ModuleRoot\internal\tepp\assignment.ps1"
# Load License
. Import-ModuleFile -Path "$ModuleRoot\internal\scripts\license.ps1"

Просмотреть файл

@ -0,0 +1 @@
# Add all things you want to run before importing the main code

Просмотреть файл

@ -0,0 +1,4 @@
<#
# Example:
Register-PSFTeppArgumentCompleter -Command Get-Alcohol -Parameter Type -Name PAWTools.alcohol
#>

Просмотреть файл

@ -0,0 +1,4 @@
<#
# Example:
Register-PSFTeppScriptblock -Name "PAWTools.alcohol" -ScriptBlock { 'Beer','Mead','Whiskey','Wine','Vodka','Rum (3y)', 'Rum (5y)', 'Rum (7y)' }
#>

Просмотреть файл

@ -0,0 +1,23 @@
# Tab Expansion
## Description
Modern Tab Expansion was opened to users with the module `Tab Expansion Plus Plus` (TEPP).
It allows you to define, what options a user is offered when tabbing through input options. This can save a lot of time for the user and is considered a key element in user experience.
The `PSFramework` offers a simplified way of offering just this, as the two example files show.
## Concept
Custom tab completion is defined in two steps:
- Define a scriptblock that is run when the user hits `TAB` and provides the strings that are his options.
- Assign that scriptblock to the parameter of a command. You can assign the same scriptblock multiple times.
## Structure
Import order matters. In order to make things work with the default scaffold, follow those rules:
- All scriptfiles _defining_ completion scriptblocks like this: `*.tepp.ps1`
- Put all your completion assignments in `assignment.ps1`

17
PAWTools/readme.md Normal file
Просмотреть файл

@ -0,0 +1,17 @@
# PSFModule guidance
This is a finished module layout optimized for implementing the PSFramework.
If you don't care to deal with the details, this is what you need to do to get started seeing results:
- Add the functions you want to publish to `/functions/`
- Update the `FunctionsToExport` node in the module manifest (PAWTools.psd1). All functions you want to publish should be in a list.
- Add internal helper functions the user should not see to `/internal/functions/`
## Path Warning
> If you want your module to be compatible with Linux and MacOS, keep in mind that those OS are case sensitive for paths and files.
`Import-ModuleFile` is preconfigured to resolve the path of the files specified, so it will reliably convert weird path notations the system can't handle.
Content imported through that command thus need not mind the path separator.
If you want to make sure your code too will survive OS-specific path notations, get used to using `Resolve-path` or the more powerful `Resolve-PSFPath`.

Просмотреть файл

@ -0,0 +1,7 @@
# Description
This is where the function tests go.
Make sure to put them in folders reflecting the actual module structure.
It is not necessary to differentiate between internal and public functions here.

Просмотреть файл

@ -0,0 +1,27 @@
# List of forbidden commands
$global:BannedCommands = @(
'Write-Host',
'Write-Verbose',
'Write-Warning',
'Write-Error',
'Write-Output',
'Write-Information',
'Write-Debug'
)
<#
Contains list of exceptions for banned cmdlets.
Insert the file names of files that may contain them.
Example:
"Write-Host" = @('Write-PSFHostColor.ps1','Write-PSFMessage.ps1')
#>
$global:MayContainCommand = @{
"Write-Host" = @()
"Write-Verbose" = @()
"Write-Warning" = @()
"Write-Error" = @()
"Write-Output" = @()
"Write-Information" = @()
"Write-Debug" = @()
}

Просмотреть файл

@ -0,0 +1,90 @@
$moduleRoot = (Resolve-Path "$PSScriptRoot\..\..").Path
. "$PSScriptRoot\FileIntegrity.Exceptions.ps1"
function Get-FileEncoding
{
<#
.SYNOPSIS
Tests a file for encoding.
.DESCRIPTION
Tests a file for encoding.
.PARAMETER Path
The file to test
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
[Alias('FullName')]
[string]
$Path
)
[byte[]]$byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path
if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf) { 'UTF8' }
elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff) { 'Unicode' }
elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff) { 'UTF32' }
elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76) { 'UTF7' }
else { 'Unknown' }
}
Describe "Verifying integrity of module files" {
Context "Validating PS1 Script files" {
$allFiles = Get-ChildItem -Path $moduleRoot -Recurse -Filter "*.ps1" | Where-Object FullName -NotLike "$moduleRoot\tests\*"
foreach ($file in $allFiles)
{
$name = $file.FullName.Replace("$moduleRoot\", '')
It "[$name] Should have UTF8 encoding" {
Get-FileEncoding -Path $file.FullName | Should -Be 'UTF8'
}
It "[$name] Should have no trailing space" {
($file | Select-String "\s$" | Where-Object { $_.Line.Trim().Length -gt 0}).LineNumber | Should -BeNullOrEmpty
}
$tokens = $null
$parseErrors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$parseErrors)
It "[$name] Should have no syntax errors" {
$parseErrors | Should Be $Null
}
foreach ($command in $global:BannedCommands)
{
if ($global:MayContainCommand["$command"] -notcontains $file.Name)
{
It "[$name] Should not use $command" {
$tokens | Where-Object Text -EQ $command | Should -BeNullOrEmpty
}
}
}
It "[$name] Should not contain aliases" {
$tokens | Where-Object TokenFlags -eq CommandName | Where-Object { Test-Path "alias:\$($_.Text)" } | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 0
}
}
}
Context "Validating help.txt help files" {
$allFiles = Get-ChildItem -Path $moduleRoot -Recurse -Filter "*.help.txt" | Where-Object FullName -NotLike "$moduleRoot\tests\*"
foreach ($file in $allFiles)
{
$name = $file.FullName.Replace("$moduleRoot\", '')
It "[$name] Should have UTF8 encoding" {
Get-FileEncoding -Path $file.FullName | Should -Be 'UTF8'
}
It "[$name] Should have no trailing space" {
($file | Select-String "\s$" | Where-Object { $_.Line.Trim().Length -gt 0 } | Measure-Object).Count | Should -Be 0
}
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
# List of functions that should be ignored
$global:FunctionHelpTestExceptions = @(
)
<#
List of arrayed enumerations. These need to be treated differently. Add full name.
Example:
"Sqlcollaborative.Dbatools.Connection.ManagementConnectionType[]"
#>
$global:HelpTestEnumeratedArrays = @(
)
<#
Some types on parameters just fail their validation no matter what.
For those it becomes possible to skip them, by adding them to this hashtable.
Add by following this convention: <command name> = @(<list of parameter names>)
Example:
"Get-DbaCmObject" = @("DoNotUse")
#>
$global:HelpTestSkipParameterType = @{
}

Просмотреть файл

@ -0,0 +1,200 @@
<#
.NOTES
The original test this is based upon was written by June Blender.
After several rounds of modifications it stands now as it is, but the honor remains hers.
Thank you June, for all you have done!
.DESCRIPTION
This test evaluates the help for all commands in a module.
.PARAMETER SkipTest
Disables this test.
.PARAMETER CommandPath
List of paths under which the script files are stored.
This test assumes that all functions have their own file that is named after themselves.
These paths are used to search for commands that should exist and be tested.
Will search recursively and accepts wildcards, make sure only functions are found
.PARAMETER ModuleName
Name of the module to be tested.
The module must already be imported
.PARAMETER ExceptionsFile
File in which exceptions and adjustments are configured.
In it there should be two arrays and a hashtable defined:
$global:FunctionHelpTestExceptions
$global:HelpTestEnumeratedArrays
$global:HelpTestSkipParameterType
These can be used to tweak the tests slightly in cases of need.
See the example file for explanations on each of these usage and effect.
#>
[CmdletBinding()]
Param (
[switch]
$SkipTest,
[string[]]
$CommandPath = @("$PSScriptRoot\..\..\functions", "$PSScriptRoot\..\..\internal\functions"),
[string]
$ModuleName = "PAWTools",
[string]
$ExceptionsFile = "$PSScriptRoot\Help.Exceptions.ps1"
)
if ($SkipTest) { return }
. $ExceptionsFile
$includedNames = (Get-ChildItem $CommandPath -Recurse -File | Where-Object Name -like "*.ps1").BaseName
$commands = Get-Command -Module (Get-Module $ModuleName) -CommandType Cmdlet, Function, Workflow | Where-Object Name -in $includedNames
## When testing help, remember that help is cached at the beginning of each session.
## To test, restart session.
foreach ($command in $commands) {
$commandName = $command.Name
# Skip all functions that are on the exclusions list
if ($global:FunctionHelpTestExceptions -contains $commandName) { continue }
# The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets
$Help = Get-Help $commandName -ErrorAction SilentlyContinue
$testhelperrors = 0
$testhelpall = 0
Describe "Test help for $commandName" {
$testhelpall += 1
if ($Help.Synopsis -like '*`[`<CommonParameters`>`]*') {
# If help is not found, synopsis in auto-generated help is the syntax diagram
It "should not be auto-generated" {
$Help.Synopsis | Should -Not -BeLike '*`[`<CommonParameters`>`]*'
}
$testhelperrors += 1
}
$testhelpall += 1
if ([String]::IsNullOrEmpty($Help.Description.Text)) {
# Should be a description for every function
It "gets description for $commandName" {
$Help.Description | Should -Not -BeNullOrEmpty
}
$testhelperrors += 1
}
$testhelpall += 1
if ([String]::IsNullOrEmpty(($Help.Examples.Example | Select-Object -First 1).Code)) {
# Should be at least one example
It "gets example code from $commandName" {
($Help.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty
}
$testhelperrors += 1
}
$testhelpall += 1
if ([String]::IsNullOrEmpty(($Help.Examples.Example.Remarks | Select-Object -First 1).Text)) {
# Should be at least one example description
It "gets example help from $commandName" {
($Help.Examples.Example.Remarks | Select-Object -First 1).Text | Should -Not -BeNullOrEmpty
}
$testhelperrors += 1
}
if ($testhelperrors -eq 0) {
It "Ran silently $testhelpall tests" {
$testhelperrors | Should -be 0
}
}
$testparamsall = 0
$testparamserrors = 0
Context "Test parameter help for $commandName" {
$Common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable',
'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'
$parameters = $command.ParameterSets.Parameters | Sort-Object -Property Name -Unique | Where-Object Name -notin $common
$parameterNames = $parameters.Name
$HelpParameterNames = $Help.Parameters.Parameter.Name | Sort-Object -Unique
foreach ($parameter in $parameters) {
$parameterName = $parameter.Name
$parameterHelp = $Help.parameters.parameter | Where-Object Name -EQ $parameterName
$testparamsall += 1
if ([String]::IsNullOrEmpty($parameterHelp.Description.Text)) {
# Should be a description for every parameter
It "gets help for parameter: $parameterName : in $commandName" {
$parameterHelp.Description.Text | Should -Not -BeNullOrEmpty
}
$testparamserrors += 1
}
$testparamsall += 1
$codeMandatory = $parameter.IsMandatory.toString()
if ($parameterHelp.Required -ne $codeMandatory) {
# Required value in Help should match IsMandatory property of parameter
It "help for $parameterName parameter in $commandName has correct Mandatory value" {
$parameterHelp.Required | Should -Be $codeMandatory
}
$testparamserrors += 1
}
if ($HelpTestSkipParameterType[$commandName] -contains $parameterName) { continue }
$codeType = $parameter.ParameterType.Name
$testparamsall += 1
if ($parameter.ParameterType.IsEnum) {
# Enumerations often have issues with the typename not being reliably available
$names = $parameter.ParameterType::GetNames($parameter.ParameterType)
if ($parameterHelp.parameterValueGroup.parameterValue -ne $names) {
# Parameter type in Help should match code
It "help for $commandName has correct parameter type for $parameterName" {
$parameterHelp.parameterValueGroup.parameterValue | Should -be $names
}
$testparamserrors += 1
}
}
elseif ($parameter.ParameterType.FullName -in $HelpTestEnumeratedArrays) {
# Enumerations often have issues with the typename not being reliably available
$names = [Enum]::GetNames($parameter.ParameterType.DeclaredMembers[0].ReturnType)
if ($parameterHelp.parameterValueGroup.parameterValue -ne $names) {
# Parameter type in Help should match code
It "help for $commandName has correct parameter type for $parameterName" {
$parameterHelp.parameterValueGroup.parameterValue | Should -be $names
}
$testparamserrors += 1
}
}
else {
# To avoid calling Trim method on a null object.
$helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() }
if ($helpType -ne $codeType) {
# Parameter type in Help should match code
It "help for $commandName has correct parameter type for $parameterName" {
$helpType | Should -be $codeType
}
$testparamserrors += 1
}
}
}
foreach ($helpParm in $HelpParameterNames) {
$testparamsall += 1
if ($helpParm -notin $parameterNames) {
# Shouldn't find extra parameters in help.
It "finds help parameter in code: $helpParm" {
$helpParm -in $parameterNames | Should -Be $true
}
$testparamserrors += 1
}
}
if ($testparamserrors -eq 0) {
It "Ran silently $testparamsall tests" {
$testparamserrors | Should -be 0
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,53 @@
Describe "Validating the module manifest" {
$moduleRoot = (Resolve-Path "$PSScriptRoot\..\..").Path
$manifest = ((Get-Content "$moduleRoot\PAWTools.psd1") -join "`n") | Invoke-Expression
[version]$moduleVersion = Get-Item "$moduleRoot\PAWTools.psm1" | Select-String -Pattern '\$script:ModuleVersion = "(.*?)"' | ForEach-Object { $_.Matches[0].Groups[1].Value }
Context "Basic resources validation" {
$files = Get-ChildItem "$moduleRoot\functions" -Recurse -File -Filter "*.ps1"
It "Exports all functions in the public folder" {
$functions = (Compare-Object -ReferenceObject $files.BaseName -DifferenceObject $manifest.FunctionsToExport | Where-Object SideIndicator -Like '<=').InputObject
$functions | Should -BeNullOrEmpty
}
It "Exports no function that isn't also present in the public folder" {
$functions = (Compare-Object -ReferenceObject $files.BaseName -DifferenceObject $manifest.FunctionsToExport | Where-Object SideIndicator -Like '=>').InputObject
$functions | Should -BeNullOrEmpty
}
It "Exports none of its internal functions" {
$files = Get-ChildItem "$moduleRoot\internal\functions" -Recurse -File -Filter "*.ps1"
$files | Where-Object BaseName -In $manifest.FunctionsToExport | Should -BeNullOrEmpty
}
It "Has the same version as the psm1 file" {
([version]$manifest.ModuleVersion) | Should -Be $moduleVersion
}
}
Context "Individual file validation" {
It "The root module file exists" {
Test-Path "$moduleRoot\$($manifest.RootModule)" | Should -Be $true
}
foreach ($format in $manifest.FormatsToProcess)
{
It "The file $format should exist" {
Test-Path "$moduleRoot\$format" | Should -Be $true
}
}
foreach ($type in $manifest.TypesToProcess)
{
It "The file $type should exist" {
Test-Path "$moduleRoot\$type" | Should -Be $true
}
}
foreach ($assembly in $manifest.RequiredAssemblies)
{
It "The file $assembly should exist" {
Test-Path "$moduleRoot\$assembly" | Should -Be $true
}
}
}
}

Просмотреть файл

@ -0,0 +1,42 @@
[CmdletBinding()]
Param (
[switch]
$SkipTest,
[string[]]
$CommandPath = @("$PSScriptRoot\..\..\functions", "$PSScriptRoot\..\..\internal\functions")
)
if ($SkipTest) { return }
$list = New-Object System.Collections.ArrayList
Describe 'Invoking PSScriptAnalyzer against commandbase' {
$commandFiles = Get-ChildItem -Path $CommandPath -Recurse -Filter "*.ps1"
$scriptAnalyzerRules = Get-ScriptAnalyzerRule
foreach ($file in $commandFiles)
{
Context "Analyzing $($file.BaseName)" {
$analysis = Invoke-ScriptAnalyzer -Path $file.FullName -ExcludeRule PSAvoidTrailingWhitespace, PSShouldProcess
forEach ($rule in $scriptAnalyzerRules)
{
It "Should pass $rule" {
If ($analysis.RuleName -contains $rule)
{
$analysis | Where-Object RuleName -EQ $rule -outvariable failures | ForEach-Object { $list.Add($_) }
1 | Should Be 0
}
else
{
0 | Should Be 0
}
}
}
}
}
}
$list | Out-Default

91
PAWTools/tests/pester.ps1 Normal file
Просмотреть файл

@ -0,0 +1,91 @@
param (
$TestGeneral = $true,
$TestFunctions = $true,
[ValidateSet('None', 'Default', 'Passed', 'Failed', 'Pending', 'Skipped', 'Inconclusive', 'Describe', 'Context', 'Summary', 'Header', 'Fails', 'All')]
$Show = "None",
$Include = "*",
$Exclude = ""
)
Write-PSFMessage -Level Important -Message "Starting Tests"
Write-PSFMessage -Level Important -Message "Importing Module"
Remove-Module PAWTools -ErrorAction Ignore
Import-Module "$PSScriptRoot\..\PAWTools.psd1"
Import-Module "$PSScriptRoot\..\PAWTools.psm1" -Force
Write-PSFMessage -Level Important -Message "Creating test result folder"
$null = New-Item -Path "$PSScriptRoot\..\.." -Name TestResults -ItemType Directory -Force
$totalFailed = 0
$totalRun = 0
$testresults = @()
#region Run General Tests
Write-PSFMessage -Level Important -Message "Modules imported, proceeding with general tests"
foreach ($file in (Get-ChildItem "$PSScriptRoot\general" -Filter "*.Tests.ps1"))
{
Write-PSFMessage -Level Significant -Message " Executing <c='em'>$($file.Name)</c>"
$TestOuputFile = Join-Path "$PSScriptRoot\..\..\TestResults" "TEST-$($file.BaseName).xml"
$results = Invoke-Pester -Script $file.FullName -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml
foreach ($result in $results)
{
$totalRun += $result.TotalCount
$totalFailed += $result.FailedCount
$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {
$name = $_.Name
$testresults += [pscustomobject]@{
Describe = $_.Describe
Context = $_.Context
Name = "It $name"
Result = $_.Result
Message = $_.FailureMessage
}
}
}
}
#endregion Run General Tests
#region Test Commands
Write-PSFMessage -Level Important -Message "Proceeding with individual tests"
foreach ($file in (Get-ChildItem "$PSScriptRoot\functions" -Recurse -File -Filter "*Tests.ps1"))
{
if ($file.Name -notlike $Include) { continue }
if ($file.Name -like $Exclude) { continue }
Write-PSFMessage -Level Significant -Message " Executing $($file.Name)"
$TestOuputFile = Join-Path "$PSScriptRoot\..\..\TestResults" "TEST-$($file.BaseName).xml"
$results = Invoke-Pester -Script $file.FullName -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml
foreach ($result in $results)
{
$totalRun += $result.TotalCount
$totalFailed += $result.FailedCount
$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {
$name = $_.Name
$testresults += [pscustomobject]@{
Describe = $_.Describe
Context = $_.Context
Name = "It $name"
Result = $_.Result
Message = $_.FailureMessage
}
}
}
}
#endregion Test Commands
$testresults | Sort-Object Describe, Context, Name, Result, Message | Format-List
if ($totalFailed -eq 0) { Write-PSFMessage -Level Critical -Message "All <c='em'>$totalRun</c> tests executed without a single failure!" }
else { Write-PSFMessage -Level Critical -Message "<c='em'>$totalFailed tests</c> out of <c='sub'>$totalRun</c> tests failed!" }
if ($totalFailed -gt 0)
{
throw "$totalFailed / $totalRun tests failed!"
}

31
PAWTools/tests/readme.md Normal file
Просмотреть файл

@ -0,0 +1,31 @@
# Description
This is the folder, where all the tests go.
Those are subdivided in two categories:
- General
- Function
## General Tests
General tests are function generic and test for general policies.
These test scan answer questions such as:
- Is my module following my style guides?
- Does any of my scripts have a syntax error?
- Do my scripts use commands I do not want them to use?
- Do my commands follow best practices?
- Do my commands have proper help?
Basically, these allow a general module health check.
These tests are already provided as part of the template.
## Function Tests
A healthy module should provide unit and integration tests for the commands & components it ships.
Only then can be guaranteed, that they will actually perform as promised.
However, as each such test must be specific to the function it tests, there cannot be much in the way of templates.

Просмотреть файл

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<!-- Foo.Bar -->
<View>
<Name>Foo.Bar</Name>
<ViewSelectedBy>
<TypeName>Foo.Bar</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize/>
<TableHeaders>
<TableColumnHeader/>
<TableColumnHeader/>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Foo</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Bar</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
<Configuration>

Просмотреть файл

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Types>
<!-- Foo.Bar -->
<Type>
<Name>Deserialized.Foo.Bar</Name>
<Members>
<MemberSet>
<Name>PSStandardMembers</Name>
<Members>
<NoteProperty>
<Name>
TargetTypeForDeserialization
</Name>
<Value>
Foo.Bar
</Value>
</NoteProperty>
</Members>
</MemberSet>
</Members>
</Type>
<Type>
<Name>Foo.Bar</Name>
<Members>
<CodeProperty IsHidden="true">
<Name>SerializationData</Name>
<GetCodeReference>
<TypeName>PSFramework.Serialization.SerializationTypeConverter</TypeName>
<MethodName>GetSerializationData</MethodName>
</GetCodeReference>
</CodeProperty>
</Members>
<TypeConverter>
<TypeName>PSFramework.Serialization.SerializationTypeConverter</TypeName>
</TypeConverter>
</Type>
</Types>

43
PAWTools/xml/readme.md Normal file
Просмотреть файл

@ -0,0 +1,43 @@
# XML
This is the folder where project XML files go, notably:
- Format XML
- Type Extension XML
External help files should _not_ be placed in this folder!
## Notes on Files and Naming
There should be only one format file and one type extension file per project, as importing them has a notable impact on import times.
- The Format XML should be named `PAWTools.Format.ps1xml`
- The Type Extension XML should be named `PAWTools.Types.ps1xml`
## Tools
### New-PSMDFormatTableDefinition
This function will take an input object and generate format xml for an auto-sized table.
It provides a simple way to get started with formats.
### Get-PSFTypeSerializationData
```
C# Warning!
This section is only interest if you're using C# together with PowerShell.
```
This function generates type extension XML that allows PowerShell to convert types written in C# to be written to file and restored from it without being 'Deserialized'. Also works for jobs or remoting, if both sides have the `PSFramework` module and type extension loaded.
In order for a class to be eligible for this, it needs to conform to the following rules:
- Have the `[Serializable]` attribute
- Be public
- Have an empty constructor
- Allow all public properties/fields to be set (even if setting it doesn't do anything) without throwing an exception.
```
non-public properties and fields will be lost in this process!
```

Просмотреть файл

@ -0,0 +1,59 @@
#Add-Log -LogEntry(Attempting to add Windows Feature RSAT-AD-PowerShell)
Import-Module ServerManager
Add-WindowsFeature RSAT-AD-PowerShell | out-null
Import-Module ActiveDirectory
Function Get-ADInfo(){
$sDSE = (Get-ADRootDSE).defaultNamingContext
return $sDSE
}
Function Get-OU($sName){
$sOU=(Get-ADOrganizationalUnit -Filter {Name -like $sName}).DistinguishedName
return $sOU
}
function Test-XADGroupObject() {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
HelpMessage="Identity of the AD object to verify if exists or not."
)]
[Object] $Identity
)
trap [Exception] {
return $false
}
$auxObject = Get-ADObject -Identity $Identity
if ($auxObject = $Identity){
return $true
}
else
{
return $false
}
}
function Test-XADObject() {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
HelpMessage="Identity of the AD object to verify if exists or not."
)]
[Object] $Identity
)
trap [Exception] {
return $false
}
$auxObject = Get-ADObject -Identity $Identity
return $true
}
Function Get-User($sName){
$sUser=(Get-ADUser -Filter {Name -like $sName}).DistinguishedName
return $sUser
}

Просмотреть файл

@ -0,0 +1,38 @@
# Create-PAWGroups.ps1
#Include PS Environment
#. ..\..\Scripts\Custom\PSEnvironment.ps1
. .\\ADEnvironment.ps1
#Configure Local Variables
$sSourceDir = Get-Location
$rootDSE = (Get-ADRootDSE).defaultNamingContext
$Groups = Import-Csv $sSourceDir"\Groups.csv"
foreach ($Group in $Groups){
$groupName = $Group.Name
$groupOUPrefix = $Group.OU
$destOU = $Group.OU + "," + $rootDSE
$groupDN = "CN=" + $groupName + "," + $destOU
#$groupDN = $Group.OU + "," + $rootDSE
# Check if the target group already is present.
$checkForGroup = Test-XADGroupObject $groupDN
If (!$checkForGroup)
{
# The group is not present, creating group.
# Add-Log -LogEntry("Creating the group " + $Group.Name + " in " + $groupDN)
New-ADGroup -Name $Group.Name -SamAccountName $Group.samAccountName -GroupCategory $Group.GroupCategory -GroupScope $Group.GroupScope -DisplayName $Group.DisplayName -Path $destOU -Description $Group.Description
If ($Group.Membership -ne ""){
# Add-Log -LogEntry("Adding " + $Group.Name + " to " + $Group.Membership);
Add-ADPrincipalGroupMembership -Identity $Group.samAccountName -MemberOf $Group.Membership;
}
$error.Clear()
}
Else
{
# The group is present, log a message.
# Add-Log -LogEntry("The group name " + $Group.Name + " already exists in the " + $destOU + " OU.")
}
}

Просмотреть файл

@ -0,0 +1,90 @@
# Create-PAWOUs.ps1
#Include PS Environment
#. ..\..\Scripts\Custom\PSEnvironment.ps1
. .\\ADEnvironment.ps1
#Get current working directory
$sLocation = Get-Location
$DomainName = (Get-ADDomain).Name
$sDSE = (Get-ADRootDSE).defaultNamingContext
#$sPath = ("OU="+ $DomainName + " Objects," + $($sDSE))
#Creating Top Level OUs
New-ADOrganizationalUnit -Name "Admin" -Path "$sDSE"
New-ADOrganizationalUnit -Name "Groups" -Path "$sDSE"
New-ADOrganizationalUnit -Name "Tier 1 Servers" -Path "$sDSE"
New-ADOrganizationalUnit -Name "Workstations" -Path "$sDSE"
New-ADOrganizationalUnit -Name "User Accounts" -Path "$sDSE"
New-ADOrganizationalUnit -Name "Computer Quarantine" -Path "$sDSE"
#Creating Sub OUs for Top Level Admin OU
New-ADOrganizationalUnit -Name "Tier 0" -Path ("OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Tier 1" -Path ("OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Tier 2" -Path ("OU=Admin,$sDSE")
#Creating Sub OUs for Admin\Tier 0 OU
New-ADOrganizationalUnit -Name "Accounts" -Path ("OU=Tier 0,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Groups" -Path ("OU=Tier 0,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Service Accounts" -Path ("OU=Tier 0,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Devices" -Path ("OU=Tier 0,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Tier 0 Servers" -Path ("OU=Tier 0,OU=Admin,$sDSE")
#Creating Sub OUs for Admin\Tier 1 OU
New-ADOrganizationalUnit -Name "Accounts" -Path ("OU=Tier 1,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Groups" -Path ("OU=Tier 1,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Service Accounts" -Path ("OU=Tier 1,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Devices" -Path ("OU=Tier 1,OU=Admin,$sDSE")
#Creating Sub OUs for Admin\Tier 2 OU
New-ADOrganizationalUnit -Name "Accounts" -Path ("OU=Tier 2,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Groups" -Path ("OU=Tier 2,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Service Accounts" -Path ("OU=Tier 2,OU=Admin,$sDSE")
New-ADOrganizationalUnit -Name "Devices" -Path ("OU=Tier 2,OU=Admin,$sDSE")
#Creating Sub OUs for Top Level Groups OU
New-ADOrganizationalUnit -Name "Security Groups" -Path ("OU=Groups,$sDSE")
New-ADOrganizationalUnit -Name "Distribution Groups" -Path ("OU=Groups,$sDSE")
New-ADOrganizationalUnit -Name "Contacts" -Path ("OU=Groups,$sDSE")
#Creating Sub OUs for Top Level Tier 1 Servers OU
New-ADOrganizationalUnit -Name "Application" -Path ("OU=Tier 1 Servers,$sDSE")
New-ADOrganizationalUnit -Name "Collaboration" -Path ("OU=Tier 1 Servers,$sDSE")
New-ADOrganizationalUnit -Name "Database" -Path ("OU=Tier 1 Servers,$sDSE")
New-ADOrganizationalUnit -Name "Messaging" -Path ("OU=Tier 1 Servers,$sDSE")
New-ADOrganizationalUnit -Name "Staging" -Path ("OU=Tier 1 Servers,$sDSE")
#Creating Sub OUs for Top Level Workstations OU
New-ADOrganizationalUnit -Name "Desktops" -Path ("OU=Workstations,$sDSE")
New-ADOrganizationalUnit -Name "Kiosks" -Path ("OU=Workstations,$sDSE")
New-ADOrganizationalUnit -Name "Laptops" -Path ("OU=Workstations,$sDSE")
New-ADOrganizationalUnit -Name "Staging" -Path ("OU=Workstations,$sDSE")
#Creating Sub OUs for Top Level User Accounts OU
New-ADOrganizationalUnit -Name "Enabled Users" -Path ("OU=User Accounts,$sDSE")
New-ADOrganizationalUnit -Name "Disabled Users" -Path ("OU=User Accounts,$sDSE")
#Block inheritance for PAW OUs
Import-Module ServerManager
Add-WindowsFeature Gpmc | Out-Null
Import-Module GroupPolicy
Set-GpInheritance -target "OU=Devices,OU=Tier 0,OU=Admin,$sDSE" -IsBlocked Yes | Out-Null
Set-GpInheritance -target "OU=Devices,OU=Tier 1,OU=Admin,$sDSE" -IsBlocked Yes | Out-Null
Set-GpInheritance -target "OU=Devices,OU=Tier 2,OU=Admin,$sDSE" -IsBlocked Yes | Out-Null
#Return to original working directory
Set-Location $sLocation

10
SourceData/Groups.csv Normal file
Просмотреть файл

@ -0,0 +1,10 @@
Name,samAccountName,GroupCategory,GroupScope,DisplayName,OU,Description,Membership
Tier 0 Replication Maintenance,Tier0ReplicationMaintenance,Security,Global,Tier 0 Replication Maintenance,"OU=Groups,OU=Tier 0,OU=Admin",Members of this group are Tier 0 Replication Maintenance,
Tier 1 Server Maintenance,Tier1ServerMaintenance,Security,Global,Tier 1 Server Maintenance,"OU=Groups,OU=Tier 1,OU=Admin",Members of this group perform Tier 1 Server Maintenance,
Service Desk Operators,ServiceDeskOperators,Security,Global,Service Desk Operators,"OU=Groups,OU=Tier 2,OU=Admin",Members of this group are Service Desk Operators,
Workstation Maintenance,WorkstationMaintenance,Security,Global,Workstation Maintenance,"OU=Groups,OU=Tier 2,OU=Admin",Members of this group perform Workstation Maintenance,
Cloud Service Admins,cloudadmins,Security,Global,Cloud Service Admins,"OU=Groups,OU=Tier 0,OU=Admin",Members of this group are permitted to connect to pre-identified cloud services via Privileged Access Workstations,
PAW Users,pawusers,Security,Global,PAW Users,"OU=Groups,OU=Tier 0,OU=Admin",Members of this group are permitted to log onto Privileged Access Workstations,
PAW Maintenance,pawmaint,Security,Global,PAW Maintenance,"OU=Groups,OU=Tier 0,OU=Admin",Members of this group maintain and support Privileged Access Workstations,
Tier 1 Admins,tier1admins,Security,Global,Tier 1 Admins,"OU=Groups,OU=Tier 1,OU=Admin",Members of this group are Tier 1 Administrators,
Tier 2 Admins,tier2admins,Security,Global,Tier 2 Admins,"OU=Groups,OU=Tier 2,OU=Admin",Members of this group are Tier 2 Administrators,
1 Name samAccountName GroupCategory GroupScope DisplayName OU Description Membership
2 Tier 0 Replication Maintenance Tier0ReplicationMaintenance Security Global Tier 0 Replication Maintenance OU=Groups,OU=Tier 0,OU=Admin Members of this group are Tier 0 Replication Maintenance
3 Tier 1 Server Maintenance Tier1ServerMaintenance Security Global Tier 1 Server Maintenance OU=Groups,OU=Tier 1,OU=Admin Members of this group perform Tier 1 Server Maintenance
4 Service Desk Operators ServiceDeskOperators Security Global Service Desk Operators OU=Groups,OU=Tier 2,OU=Admin Members of this group are Service Desk Operators
5 Workstation Maintenance WorkstationMaintenance Security Global Workstation Maintenance OU=Groups,OU=Tier 2,OU=Admin Members of this group perform Workstation Maintenance
6 Cloud Service Admins cloudadmins Security Global Cloud Service Admins OU=Groups,OU=Tier 0,OU=Admin Members of this group are permitted to connect to pre-identified cloud services via Privileged Access Workstations
7 PAW Users pawusers Security Global PAW Users OU=Groups,OU=Tier 0,OU=Admin Members of this group are permitted to log onto Privileged Access Workstations
8 PAW Maintenance pawmaint Security Global PAW Maintenance OU=Groups,OU=Tier 0,OU=Admin Members of this group maintain and support Privileged Access Workstations
9 Tier 1 Admins tier1admins Security Global Tier 1 Admins OU=Groups,OU=Tier 1,OU=Admin Members of this group are Tier 1 Administrators
10 Tier 2 Admins tier2admins Security Global Tier 2 Admins OU=Groups,OU=Tier 2,OU=Admin Members of this group are Tier 2 Administrators

Просмотреть файл

@ -0,0 +1 @@
*.aspnetcdn.com;*.aadrm.com;*.appex.bing.com;*.appex-rf.msn.com;*.assets-yammer.com;*.azure.com;*.azurecomcdn.net;*.cloudappsecurity.com;*.c.bing.com;*.gfx.ms;*.live.com;*.live.net;*.lync.com;maodatafeedsservice.cloudapp.net;*.microsoft.com;*.microsoftonline.com;*.microsoftonline-p.com;*.microsoftonline-p.net;*.microsoftonlineimages.com;*.microsoftonlinesupport.net;ms.tific.com;*.msecnd.net;*.msedge.net;*.msft.net;*.msocdn.com;*.onenote.com;*.outlook.com;*.office365.com;*.office.com;*.office.net;*.onmicrosoft.com;partnerservices.getmicrosoftkey.com;*.passport.net;*.phonefactor.net;*.s-microsoft.com;*.s-msn.com;*.sharepoint.com;*.sharepointonline.com;*.s-msn.com;spoprod-a.akamaihd.net;*.symcb.com;*.yammer.com;*.yammerusercontent.com;*.verisign.com;*.windows.com;*.windows.net;*.windowsazure.com;*.windowsupdate.com

Просмотреть файл

@ -0,0 +1,204 @@
# Delegate-PAWOURights.ps1
# Based on and includes the DIAD delegations by Heath Aubin and Jon Sabberton
#Include PS Environment
#. ..\..\Scripts\Custom\PSEnvironment.ps1
. .\\ADEnvironment.ps1
# Add-Log -LogEntry("--Beginning PAW and DIAD Active Directory Delegations--");
#Get current working directory
$sLocation = Get-Location
#Bring up an Active Directory command prompt so we can use this later on in the script
Set-Location ad:
#Get a reference to the RootDSE of the current domain
$rootdse = Get-ADRootDSE
#Get a reference to the current domain
$domain = Get-ADDomain
#Set the Configuration Naming Context
$configCN = $rootdse.ConfigurationNamingContext
#Set the Schema Naming Context
$schemaNC = $rootDSE.SchemaNamingContext
#Set the ForestDnsZones Naming Context
$forestDnsZonesDN = "DC=ForestDnsZones,"+$rootDSE.RootDomainNamingContext
#Set the Sites Naming Context
$sitesDN = "CN=Sites,"+$configCN
#Create a hashtable to store the GUID value of each schema class and attribute
$guidmap = @{}
Get-ADObject -SearchBase ($rootdse.SchemaNamingContext) -LDAPFilter `
"(schemaidguid=*)" -Properties lDAPDisplayName,schemaIDGUID |
% {$guidmap[$_.lDAPDisplayName]=[System.GUID]$_.schemaIDGUID}
#Create a hashtable to store the GUID value of each extended right in the forest
$extendedrightsmap = @{}
Get-ADObject -SearchBase ($rootdse.ConfigurationNamingContext) -LDAPFilter `
"(&(objectclass=controlAccessRight)(rightsguid=*))" -Properties displayName,rightsGuid |
% {$extendedrightsmap[$_.displayName]=[System.GUID]$_.rightsGuid}
# Set variables for OUs and Containers
$userAccountsOU = "OU=User Accounts,"
$workstationsOU = "OU=Workstations,"
$computerQuarantineOU = "OU=Computer Quarantine,"
$tier1ServersOU = "OU=Tier 1 Servers,"
$PAWDevicesOU = "OU=Devices,OU=Tier 0,OU=Admin,"
# Set variables for Group objects
$serviceDeskOperatorsGroup = "ServiceDeskOperators"
$workstationMaintenanceGroup = "WorkstationMaintenance"
$replicationMaintenanceGroup = "Tier0ReplicationMaintenance"
$tier1ServerMaintenanceGroup = "Tier1ServerMaintenance"
$PAWAdminsGroup = "PAWMaint"
#Get a reference to each of the OU's we want to set permissions on
#Add-Log -LogEntry("Getting OU Information");
$userAcctsOUDN = Get-ADOrganizationalUnit -Identity ($userAccountsOU+$domain)
$workstationsOUDN = Get-ADOrganizationalUnit -Identity ($workstationsOU+$domain)
$computerQuarantineOUDN = Get-ADOrganizationalUnit -Identity ($computerQuarantineOU+$domain)
$tier1ServersOUDN = Get-ADOrganizationalUnit -Identity ($tier1ServersOU+$domain)
$PAWDevicesOUDN = Get-ADOrganizationalUnit -Identity ($PAWDevicesOU+$domain)
#Get the SID values of each group (principal) we wish to delegate access to
#Add-Log -LogEntry("Getting SID values for each group for delegations");
$serviceDeskOpsSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup $serviceDeskOperatorsGroup).SID
$workstationMaintSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup $workstationMaintenanceGroup).SID
$replMaintGroupSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup $replicationMaintenanceGroup).SID
$tier1ServerMaintGroupSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup $tier1ServerMaintenanceGroup).SID
$PAWAdminsGroupSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup $PAWAdminsGroup).SID
#Get a copy of the current DACL on the OU's or Containers
#Add-Log -LogEntry("Getting existing Directory ACLs");
$userAccountsOUACL = Get-ACL -Path ($userAcctsOUDN);
$workstationsOUACL = Get-ACL -Path ($workstationsOUDN);
$computerQuarantineACL = Get-ACL -Path ($computerQuarantineOUDN)
$topLevelDomainACL = Get-ACL -Path($domain)
$configContainerACL = Get-ACL -Path($configCN)
$schemaNCACL = Get-ACL -Path($schemaNC)
$forestDnsZonesACL = Get-ACL -Path($forestDnsZonesDN)
$sitesACL = Get-ACL -Path($sitesDN)
$tier1ServersOUACL = Get-ACL -Path ($tier1ServersOUDN)
$PAWDevicesOUACL = Get-ACL -Path ($PAWDevicesOUDN)
#Set Service Desk Operators Permissions to Users
#Add-Log -LogEntry("Performing Service Desk Operators Role Delegations User Accounts OU");
$userAccountsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"ReadProperty","Allow","Descendents",$guidmap["user"]))
$userAccountsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"WriteProperty","Allow","Descendents",$guidmap["user"]))
$userAccountsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"ExtendedRight","Allow",$extendedrightsmap["Reset Password"],"Descendents",$guidmap["user"]))
#Set Service Desk Operator Permissions on Computers to access BitLocker and TPM information
#Add-Log -LogEntry("Performing Service Desk Operator Role Delegations to the Workstation OU");
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"ReadProperty","Allow",$guidmap["msTPM-OwnerInformation"],"Descendents",$guidmap["computer"]))
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"ReadProperty","Allow",$guidmap["msFVE-KeyPackage"],"Descendents",$guidmap["msFVE-RecoveryInformation"]))
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"ReadProperty","Allow",$guidmap["msFVE-RecoveryPassword"],"Descendents",$guidmap["msFVE-RecoveryInformation"]))
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$serviceDeskOpsSID,"ReadProperty","Allow",$guidmap["msFVE-VolumeGuid"],"Descendents",$guidmap["msFVE-RecoveryInformation"]))
#Set Workstation Maintenance Permissions on Computer objects in the Computer Quarantine OU
#Add-Log -LogEntry("Performing Workstation Maintenance Role Delegations to the Computer Quarantine OU");
$computerQuarantineACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$workstationMaintSID,"CreateChild,DeleteChild","Allow",$guidmap["computer"],"All"))
$computerQuarantineACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$workstationMaintSID,"ReadProperty","Allow","Descendents",$guidmap["computer"]))
$computerQuarantineACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$workstationMaintSID,"WriteProperty","Allow","Descendents",$guidmap["computer"]))
#Set Workstation Maintenance Permissions on Computer objects in the Workstations OU
#Add-Log -LogEntry("Performing Workstation Maintenance Role Delegations to the Workstations OU");
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$workstationMaintSID,"CreateChild,DeleteChild","Allow",$guidmap["computer"],"All"))
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$workstationMaintSID,"ReadProperty","Allow","Descendents",$guidmap["computer"]))
$workstationsOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$workstationMaintSID,"WriteProperty","Allow","Descendents",$guidmap["computer"]))
#Set PAW Admins Permissions on Computer objects in the PAW Devices OU
#Add-Log -LogEntry("Performing PAW Admins Role Delegations to the Tier 0\Devices OU");
$PAWDevicesOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$PAWAdminsGroupSID,"CreateChild,DeleteChild","Allow",$guidmap["computer"],"All"))
$PAWDevicesOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$PAWAdminsGroupSID,"ReadProperty","Allow","Descendents",$guidmap["computer"]))
$PAWDevicesOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$PAWAdminsGroupSID,"WriteProperty","Allow","Descendents",$guidmap["computer"]))
#Set Tier 0 Replication Maintenance Permissions within domain
#Add-Log -LogEntry("Performing Tier 0 Replication Maintenance Role Delegations");
$topLevelDomainACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Manage Replication Topology"],"Descendents"))
$topLevelDomainACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes"],"Descendents"))
$topLevelDomainACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes All"],"Descendents"))
$topLevelDomainACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replication Synchronization"],"Descendents"))
$configContainerACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Manage Replication Topology"],"Descendents"))
$configContainerACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes"],"Descendents"))
$configContainerACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes All"],"Descendents"))
$configContainerACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replication Synchronization"],"Descendents"))
$configContainerACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Monitor active directory Replication"],"Descendents"))
$schemaNCACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Manage Replication Topology"],"Descendents"))
$schemaNCACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes"],"Descendents"))
$schemaNCACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes All"],"Descendents"))
$schemaNCACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replication Synchronization"],"Descendents"))
$schemaNCACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Monitor active directory Replication"],"Descendents"))
$forestDnsZonesACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Manage Replication Topology"],"Descendents"))
$forestDnsZonesACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes"],"Descendents"))
$forestDnsZonesACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replicating Directory Changes All"],"Descendents"))
$forestDnsZonesACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"ExtendedRight","Allow",$extendedrightsmap["Replication Synchronization"],"Descendents"))
$sitesACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"CreateChild,DeleteChild","Allow"))
$sitesACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$replMaintGroupSID,"WriteProperty","Allow"))
#Set Tier 1 Server Maintenance Permissions on Computer objects in the Tier 1 Servers OU
#Add-Log -LogEntry("Performing Tier 1 Server Maintenance Role Delegations to the Tier 1 Servers OU");
$tier1ServersOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$tier1ServerMaintGroupSID,"CreateChild,DeleteChild","Allow",$guidmap["computer"],"All"))
$tier1ServersOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$tier1ServerMaintGroupSID,"ReadProperty","Allow","Descendents",$guidmap["computer"]))
$tier1ServersOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$tier1ServerMaintGroupSID,"WriteProperty","Allow","Descendents",$guidmap["computer"]))
$tier1ServersOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$tier1ServerMaintGroupSID,"ReadProperty,WriteProperty","Allow",$guidmap["gplink"],"All"))
$tier1ServersOUACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
$tier1ServerMaintGroupSID,"ReadProperty","Allow",$guidmap["gpoptions"],"All"))
#Apply the modified DACL to the OU or Containers
#Add-Log -LogEntry("Applying all Updated ACLs");
Set-ACL -ACLObject $userAccountsOUACL -Path ("AD:\"+($userAcctsOUDN));
Set-ACL -ACLObject $workstationsOUACL -Path ("AD:\"+($workstationsOUDN));
Set-ACL -ACLObject $computerQuarantineACL -Path ("AD:\"+($computerQuarantineOUDN));
Set-ACL -ACLObject $topLevelDomainACL -Path ("AD:\"+($domain));
Set-ACL -ACLObject $configContainerACL -Path ("AD:\"+($configCN));
Set-ACL -ACLObject $schemaNCACL -Path ("AD:\"+($schemaNC));
Set-ACL -ACLObject $forestDnsZonesACL -Path ("AD:\"+($forestDnsZonesDN));
Set-ACL -ACLObject $sitesACL -Path ("AD:\"+($sitesDN));
Set-ACL -ACLObject $tier1ServersOUACL -Path ("AD:\"+($tier1ServersOUDN));
Set-ACL -ACLObject $PAWDevicesOUACL -Path ("AD:"+($PAWDevicesOUDN));
#Add-Log -LogEntry("--Completed PAW and DIAD Active Directory Delegations--");
#Return to original working directory
Set-Location $sLocation

Просмотреть файл

@ -0,0 +1,39 @@
CLASS USER
CATEGORY "Internet Proxy Settings"
KEYNAME "Software\Microsoft\Windows\CurrentVersion\Internet Settings"
POLICY "Automatic configuration"
EXPLAIN "Configure the automatic proxy configuration settings, including: Checkbox to automatically detect settings Automatic configuration script URL (example: http://proxy.example:8080/proxy.pac). Leave URL blank to disable auto-config script."
PART "Automatically detect settings" DROPDOWNLIST
VALUENAME "AutoDetect"
ITEMLIST
NAME Disabled VALUE NUMERIC 0
NAME Enabled VALUE NUMERIC 1
END ITEMLIST
NOSORT
END PART
PART "Use automatic configuration script:" EDITTEXT
VALUENAME "AutoConfigUrl"
END PART
END POLICY
POLICY "Proxy server"
EXPLAIN "Configure the proxy server settings, including: Checkbox to use a proxy server; proxy server address and port number (example: server:port) Proxy exceptions/bypass list (example: *.microsoft.com;*.windowsazure.com;<local>). Note: Include <local> in the bypass list to bypass the proxy for local addresses."
PART "Use a proxy server" DROPDOWNLIST
VALUENAME "ProxyEnable"
ITEMLIST
NAME Enabled VALUE NUMERIC 1
NAME Disabled VALUE NUMERIC 0
END ITEMLIST
NOSORT
END PART
PART "Proxy address and port number:" EDITTEXT
VALUENAME "ProxyServer"
END PART
PART "Exceptions - Do not use proxy server for addresses beginning with:" EDITTEXT
VALUENAME "ProxyOverride"
END PART
END POLICY
END CATEGORY

Двоичные данные
SourceData/pawfirewallupdate.wfw Normal file

Двоичный файл не отображается.

52
SourceData/proxy.pac Normal file
Просмотреть файл

@ -0,0 +1,52 @@
function FindProxyForURL(url, host) {
if (shExpMatch(host, "*.aspnetcdn.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.aadrm.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.appex.bing.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.appex-rf.msn.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.assets-yammer.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.azure.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.azurecomcdn.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.cloudappsecurity.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.c.bing.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.gfx.ms")) { return "DIRECT"; }
if (shExpMatch(host, "*.live.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.live.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.lync.com")) { return "DIRECT"; }
if (shExpMatch(host, "maodatafeedsservice.cloudapp.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.microsoft.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.microsoftonline.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.microsoftonline-p.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.microsoftonline-p.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.microsoftonlineimages.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.microsoftonlinesupport.net")) { return "DIRECT"; }
if (shExpMatch(host, "ms.tific.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.msecnd.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.msedge.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.msft.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.msocdn.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.onenote.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.outlook.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.office365.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.office.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.office.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.onmicrosoft.com")) { return "DIRECT"; }
if (shExpMatch(host, "partnerservices.getmicrosoftkey.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.passport.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.phonefactor.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.s-microsoft.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.s-msn.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.sharepoint.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.sharepointonline.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.s-msn.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.symcb.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.yammer.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.yammerusercontent.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.verisign.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.windows.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.windows.net")) { return "DIRECT"; }
if (shExpMatch(host, "*.windowsazure.com")) { return "DIRECT"; }
if (shExpMatch(host, "*.windowsupdate.com")) { return "DIRECT"; }
return "PROXY 127.0.0.2:8080";
}

7
build/filesAfter.txt Normal file
Просмотреть файл

@ -0,0 +1,7 @@
# List all files that are loaded in the preimport.ps1
# In the order they are loaded during preimport
internal\configurations\*.ps1
internal\tepp\*.tepp.ps1
internal\tepp\assignment.ps1
internal\scripts\license.ps1

2
build/filesBefore.txt Normal file
Просмотреть файл

@ -0,0 +1,2 @@
# List all files that are loaded in the postimport.ps1
# In the order they are loaded during postimport

65
build/vsts-build.ps1 Normal file
Просмотреть файл

@ -0,0 +1,65 @@
<#
This script publishes the module to the gallery.
It expects as input an ApiKey authorized to publish the module.
Insert any build steps you may need to take before publishing it here.
#>
param (
$ApiKey
)
# Prepare publish folder
Write-PSFMessage -Level Important -Message "Creating and populating publishing directory"
$publishDir = New-Item -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY -Name publish -ItemType Directory
Copy-Item -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)\PAWTools" -Destination $publishDir.FullName -Recurse -Force
# Create commands.ps1
$text = @()
Get-ChildItem -Path "$($publishDir.FullName)\PAWTools\internal\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object {
$text += [System.IO.File]::ReadAllText($_.FullName)
}
Get-ChildItem -Path "$($publishDir.FullName)\PAWTools\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object {
$text += [System.IO.File]::ReadAllText($_.FullName)
}
$text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\PAWTools\commands.ps1"
# Create resourcesBefore.ps1
$processed = @()
$text = @()
foreach ($line in (Get-Content "$($PSScriptRoot)\filesBefore.txt" | Where-Object { $_ -notlike "#*" }))
{
if ([string]::IsNullOrWhiteSpace($line)) { continue }
$basePath = Join-Path "$($publishDir.FullName)\PAWTools" $line
foreach ($entry in (Resolve-PSFPath -Path $basePath))
{
$item = Get-Item $entry
if ($item.PSIsContainer) { continue }
if ($item.FullName -in $processed) { continue }
$text += [System.IO.File]::ReadAllText($item.FullName)
$processed += $item.FullName
}
}
if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\PAWTools\resourcesBefore.ps1" }
# Create resourcesAfter.ps1
$processed = @()
$text = @()
foreach ($line in (Get-Content "$($PSScriptRoot)\filesAfter.txt" | Where-Object { $_ -notlike "#*" }))
{
if ([string]::IsNullOrWhiteSpace($line)) { continue }
$basePath = Join-Path "$($publishDir.FullName)\PAWTools" $line
foreach ($entry in (Resolve-PSFPath -Path $basePath))
{
$item = Get-Item $entry
if ($item.PSIsContainer) { continue }
if ($item.FullName -in $processed) { continue }
$text += [System.IO.File]::ReadAllText($item.FullName)
$processed += $item.FullName
}
}
if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\PAWTools\resourcesAfter.ps1" }
# Publish to Gallery
Publish-Module -Path "$($publishDir.FullName)\PAWTools" -NuGetApiKey $ApiKey -Force

Просмотреть файл

@ -0,0 +1,6 @@
Write-Host "Installing Pester" -ForegroundColor Cyan
Install-Module Pester -Force -SkipPublisherCheck
Write-Host "Installing PSFramework" -ForegroundColor Cyan
Install-Module PSFramework -Force -SkipPublisherCheck
Write-Host "Installing PSScriptAnalyzer" -ForegroundColor Cyan
Install-Module PSScriptAnalyzer -Force -SkipPublisherCheck

7
build/vsts-validate.ps1 Normal file
Просмотреть файл

@ -0,0 +1,7 @@
# Guide for available variables and working with secrets:
# https://docs.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/variables?tabs=powershell
# Needs to ensure things are Done Right and only legal commits to master get built
# Run internal pester tests
& "$PSScriptRoot\..\PAWTools\tests\pester.ps1"

2431
install.ps1 Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{EC2B8D89-78FD-4DD8-8E9E-4A3A53F9970A}") = "PAWTools", "PAWTools\PAWTools.csproj", "{00DDCA14-4036-4C63-AAB8-584416D3205D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{00DDCA14-4036-4C63-AAB8-584416D3205D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00DDCA14-4036-4C63-AAB8-584416D3205D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00DDCA14-4036-4C63-AAB8-584416D3205D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00DDCA14-4036-4C63-AAB8-584416D3205D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2D4983EE-D5B2-4AAE-AECA-152DECE8E6F3}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,8 @@
using System;
namespace PAWTools
{
public class Class1
{
}
}

Просмотреть файл

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net4.5.2</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\..\..\PAWTools\bin</OutputPath>
<DocumentationFile>..\..\..\PAWTools\bin\PAWTools.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Release)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\..\..\PAWTools\bin</OutputPath>
<DocumentationFile>..\..\..\PAWTools\bin\PAWTools.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
</Project>