FileSystemHelper.psm1
function Get-FileSystemObjectSecurity { [CmdletBinding()] [OutputType([NtfsPermissionsHelper.PermissionCollection])] param ( # Path [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [string]$Path ) Begin { $FunctionName = $MyInvocation.MyCommand.Name } Process { $errPref = $ErrorActionPreference $ErrorActionPreference = 'Stop' try { [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) } catch { Write-Error -Exception "$_" -Message "$_" -Category NotSpecified -ErrorId 0 -TargetObject $FunctionName -ErrorAction $errPref } } End { } } function Set-FileSystemObjectSecurity { [CmdletBinding(DefaultParameterSetName="NoRemoting_ByPermissionList")] [OutputType([NtfsPermissionsHelper.PermissionCollection])] param ( # Path [Parameter(Mandatory=$true)] [string]$Path, # PermissionCollection [Parameter(Mandatory=$true, ParameterSetName="NoRemoting_ByPermissionsObject")] [NtfsPermissionsHelper.PermissionCollection]$PermissionCollection, # ExplicitPermissions [Parameter(Mandatory=$false, ParameterSetName="NoRemoting_ByPermissionList")] [NtfsPermissionsHelper.PermissionEntry[]]$ExplicitPermissions, # BreakInheritance [Parameter(Mandatory=$false, ParameterSetName="NoRemoting_ByPermissionList")] [switch]$BreakInheritance, # PreserveInheritedRules [Parameter(Mandatory=$false, ParameterSetName="NoRemoting_ByPermissionList")] [switch]$PreserveInheritedRules, # PassThru [Parameter(Mandatory=$false)] [switch]$PassThru ) Begin { $FunctionName = $MyInvocation.MyCommand.Name } Process { $errPref = $ErrorActionPreference $ErrorActionPreference = 'Stop' try { switch($PSCmdlet.ParameterSetName) { "NoRemoting_ByPermissionsObject" { $PermissionCollection.SetPermissions($Path) } "NoRemoting_ByPermissionList" { $SecurityObj = [NtfsPermissionsHelper.PermissionCollection]::CreateNew() if($BreakInheritance.IsPresent) { $SecurityObj.InheritanceIsBroken = $true if($PreserveInheritedRules.IsPresent) { $CurrentSecurity = [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) $SecurityObj.ExplicitPermissions.AddRange($CurrentSecurity.InheritedPermissions) } } if($ExplicitPermissions) { $SecurityObj.ExplicitPermissions.AddRange($ExplicitPermissions) } $SecurityObj.SetPermissions($Path) } } if($PassThru.IsPresent) { [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) } } catch { Write-Error -Exception "$_" -Message "$_" -Category NotSpecified -ErrorId 0 -TargetObject $FunctionName -ErrorAction $errPref } } End { } } function Set-FileSystemObjectOwner { [CmdletBinding()] [OutputType([NtfsPermissionsHelper.PermissionCollection])] param ( # Path [Parameter(Position=0, Mandatory=$true)] [string]$Path, # Identity [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentity')] [ValidateNotNull()] [string]$Identity, # IdentityReference [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityReference')] [ValidateNotNull()] [System.Security.Principal.IdentityReference]$IdentityReference, # DomainName [Parameter(Mandatory=$false, ParameterSetName='NoRemoting_ByUserName')] [AllowNull()] [AllowEmptyString()] [string]$DomainName, # UserName [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByUserName')] [ValidateNotNullOrEmpty()] [string]$UserName, # PassThru [Parameter(Mandatory=$false)] [switch]$PassThru ) Begin { $FunctionName = $MyInvocation.MyCommand.Name } Process { $errPref = $ErrorActionPreference $ErrorActionPreference = 'Stop' try { if($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByIdentity") { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($Identity) } elseif($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByIdentityReference") { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($IdentityReference) } elseif($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByUserName") { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($DomainName,$UserName) } $SecurityObj = [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) $SecurityObj.Owner = $AceAccount # [NtfsPermissionsHelper.TokenPrivilegeHelper]::EnablePrivilege([NtfsPermissionsHelper.PrivilegeNames]::SeBackupPrivilege) $HasPrivilege = [NtfsPermissionsHelper.TokenPrivilegeHelper]::EnablePrivilege([NtfsPermissionsHelper.PrivilegeNames]::SeRestorePrivilege) $SecurityObj.SetOwner($Path) if($PassThru.IsPresent) { [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) } } catch { Write-Error -Exception "$_" -Message "$_" -Category NotSpecified -ErrorId 0 -TargetObject $FunctionName -ErrorAction $errPref } } End { } } function New-PermissionEntry { [CmdletBinding()] [OutputType([NtfsPermissionsHelper.PermissionEntry])] param ( # Identity [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityAndCommonRights')] [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityAndSpecialRights')] [ValidateNotNull()] [string]$Identity, # IdentityReference [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityReferenceAndCommonRights')] [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityReferenceAndSpecialRights')] [ValidateNotNull()] [System.Security.Principal.IdentityReference]$IdentityReference, # DomainName [Parameter(Mandatory=$false, ParameterSetName='NoRemoting_ByUserNameAndCommonRights')] [Parameter(Mandatory=$false, ParameterSetName='NoRemoting_ByUserNameAndSpecialRights')] [AllowNull()] [AllowEmptyString()] [string]$DomainName, # UserName [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByUserNameAndCommonRights')] [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByUserNameAndSpecialRights')] [ValidateNotNullOrEmpty()] [string]$UserName, # AppliesTo (This parameter is ignored for files. It is valid only for folders.) [Parameter(Mandatory=$false)] [NtfsPermissionsHelper.AppliesToOptions]$AppliesTo = [NtfsPermissionsHelper.AppliesToOptions]::ThisFolderSubfoldersAndFiles, # CommonRights [Parameter(Mandatory=$false, ParameterSetName='NoRemoting_ByIdentityAndCommonRights')] [Parameter(Mandatory=$false, ParameterSetName='NoRemoting_ByIdentityReferenceAndSpecialRights')] [Parameter(Mandatory=$false, ParameterSetName='NoRemoting_ByUserNameAndCommonRights')] [NtfsPermissionsHelper.CommonRights]$CommonRights = [NtfsPermissionsHelper.CommonRights]::FullControl, # SpecialRights [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityAndSpecialRights')] [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByIdentityReferenceAndSpecialRights')] [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByUserNameAndSpecialRights')] [ValidateSet('AppendData', 'ChangePermissions', 'CreateDirectories', 'CreateFiles', 'Delete', 'DeleteSubdirectoriesAndFiles', 'ExecuteFile', 'FullControl', 'ListDirectory', 'Modify', 'Read', 'ReadAndExecute', 'ReadAttributes', 'ReadData', 'ReadExtendedAttributes', 'ReadPermissions', 'TakeOwnership', 'Traverse', 'Write', 'WriteAttributes', 'WriteData', 'WriteExtendedAttributes')] [string[]]$SpecialRights, # AccessType [Parameter(Mandatory=$false)] [NtfsPermissionsHelper.AccessTypeOptions]$AccessType = [NtfsPermissionsHelper.AccessTypeOptions]::Allow, # WellKnownACE [Parameter(Mandatory=$true, ParameterSetName='NoRemoting_ByWellKnownACE')] [ValidateSet('LocalAdministrators','CreatorOwner','LocalSystem')] [string[]]$WellKnownACE ) Begin { $FunctionName = $MyInvocation.MyCommand.Name } Process { $errPref = $ErrorActionPreference $ErrorActionPreference = 'Stop' try { if($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByWellKnownACE") { if($WellKnownACE -contains 'LocalAdministrators') { $AceAccount = [AccountManagement.IdentityInfo]::Resolve('BUILTIN','Administrators') [NtfsPermissionsHelper.PermissionEntry]::CreateNew($AceAccount) } if($WellKnownACE -contains 'LocalSystem') { $AceAccount = [AccountManagement.IdentityInfo]::Resolve('NT AUTHORITY','SYSTEM') [NtfsPermissionsHelper.PermissionEntry]::CreateNew($AceAccount) } if($WellKnownACE -contains 'CreatorOwner') { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($null,'CREATOR OWNER') [NtfsPermissionsHelper.PermissionEntry]::CreateNew($AceAccount,[NtfsPermissionsHelper.CommonRights]::FullControl,[NtfsPermissionsHelper.AppliesToOptions]::SubfoldersAndFilesOnly) } } else { if($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByIdentityAnd*") { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($Identity) } elseif($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByIdentityReferenceAnd*") { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($IdentityReference) } elseif($($PSCmdlet.ParameterSetName) -like "NoRemoting_ByUserNameAnd*") { $AceAccount = [AccountManagement.IdentityInfo]::Resolve($DomainName,$UserName) } $entryObj = [NtfsPermissionsHelper.PermissionEntry]::CreateNew($AceAccount,$CommonRights,$AppliesTo,$AccessType) if($($PSCmdlet.ParameterSetName) -like "*SpecialRights") { $SpecialRightsFlags = $($SpecialRights | ForEach-Object -Begin { $flags = 0; } -Process { $flags = $($flags -bor $([System.Security.AccessControl.FileSystemRights]$_)); } -End { [System.Security.AccessControl.FileSystemRights]$flags }) $entryObj.FileSystemRights = $SpecialRightsFlags } $entryObj } } catch { Write-Error -Exception "$_" -Message "$_" -Category NotSpecified -ErrorId 0 -TargetObject $FunctionName -ErrorAction $errPref } } End { } } function Add-FileSystemObjectPermissionEntry { [CmdletBinding()] [OutputType([NtfsPermissionsHelper.PermissionCollection])] param ( # Path [Parameter(Mandatory=$true)] [string]$Path, # Identity [Parameter(Mandatory=$true)] [ValidateNotNull()] [NtfsPermissionsHelper.PermissionEntry]$PermissionEntry, # Force [Parameter(Mandatory=$false)] [switch]$Force, # PassThru [Parameter(Mandatory=$false)] [switch]$PassThru ) Begin { $FunctionName = $MyInvocation.MyCommand.Name } Process { $errPref = $ErrorActionPreference $ErrorActionPreference = 'Stop' try { $Permissions = [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) if($($PermissionEntry.MatchesItemInCollection($Permissions.ExplicitPermissions)) -and ( -not $($Force.IsPresent))) { Write-Verbose "The specified Permission Entry is already configured on object $($Path):$PermissionEntry" } else { Write-Verbose "Adding PermissionEntry on object $($Path):$PermissionEntry" $Permissions.ExplicitPermissions.Add($PermissionEntry) $Permissions.SetPermissions($Path) } if($PassThru.IsPresent) { [NtfsPermissionsHelper.PermissionCollection]::GetSecurity($Path) } } catch { Write-Error -Exception "$_" -Message "$_" -Category NotSpecified -ErrorId 0 -TargetObject $FunctionName -ErrorAction $errPref } } End { } } function Wait-FileSystemItemLock { [CmdletBinding()] param ( #FilePath [Parameter(Mandatory=$true)] [System.IO.FileInfo]$FilePath, #WaitTimeoutInSeconds [Parameter(Mandatory=$false)] [int]$WaitTimeoutInSeconds = 300, #WaitIntervalInSeconds [Parameter(Mandatory=$false)] [int]$WaitIntervalInSeconds = 2 ) process { $Timer = [System.Diagnostics.Stopwatch]::StartNew() while (!$FileIsUnlocked) { #Check File try { $FileOpen = $FilePath.Open([System.IO.FileMode]::Truncate) $FileIsUnlocked = $true } catch { $FileIsUnlocked = $false } #Check Timeout if ($Timer.Elapsed.TotalSeconds -ge $WaitTimeoutInSeconds) { throw "Item: $($FilePath.FullName) is still Locked, timeout of $WaitTimeoutInSeconds reaced." } #Sleep if (!$FileIsUnlocked) { Start-Sleep -Seconds $WaitIntervalInSeconds } } } } function Find-FileSharedPath { [CmdletBinding()] [OutputType([void])] param ( #FilePath [Parameter(Mandatory=$true,ParameterSetName='NoRemoting_Default')] [string]$FilePath, #ReplaceMachineFQDN [Parameter(Mandatory=$false,ParameterSetName='NoRemoting_Default')] [string]$ReplaceMachineFQDN ) Process { if ($PSBoundParameters.ContainsKey('ReplaceMachineFQDN')) { $ComputerFqdn = $ReplaceMachineFQDN } else { $DomainFQDN= (Get-WmiObject Win32_ComputerSystem).Domain $ComputerFqdn = "$env:COMPUTERNAME.$DomainFQDN" } $allShares = Get-SmbShare -Special:$false $MatchingShares = $allShares | Where-Object {$FilePath.StartsWith($_.Path,[System.StringComparison]::OrdinalIgnoreCase)} | Sort-Object -Property Name | select -First 1 -ErrorAction Stop if ($MatchingShares) { $FilePath.Replace($MatchingShares.path,"\\$ComputerFqdn\$($MatchingShares.Name)") } else { throw "No Shared paths to: $FilePath" } } } |