-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from LarryWisherMan/feature/FunctionEnhancements
Feature/function enhancements
- Loading branch information
Showing
10 changed files
with
857 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<# | ||
.SYNOPSIS | ||
Retrieves non-special user profile information from a remote or local computer. | ||
.DESCRIPTION | ||
The Get-SIDProfileInfoFallback function uses the CIM (Common Information Model) method to retrieve user profile | ||
information from the specified computer. It filters out special profiles and returns the SID, profile path, and other | ||
relevant information for each user profile found on the system. This function serves as a fallback method for obtaining | ||
profile information without requiring administrative privileges to access the registry. | ||
.PARAMETER ComputerName | ||
The name of the computer to query for user profiles. If not provided, the function will default to the local computer. | ||
.OUTPUTS | ||
[PSCustomObject[]] | ||
Returns an array of PSCustomObject where each object contains: | ||
- SID: The security identifier for the user profile. | ||
- ProfilePath: The local file system path to the user profile. | ||
- ComputerName: The name of the computer from which the profile was retrieved. | ||
- ExistsInRegistry: Always set to $true, as this function is a fallback and does not query the registry directly. | ||
.EXAMPLE | ||
Get-SIDProfileInfoFallback | ||
Retrieves non-special user profiles from the local computer and returns their SID, profile path, and other details. | ||
.EXAMPLE | ||
Get-SIDProfileInfoFallback -ComputerName "Server01" | ||
Retrieves non-special user profiles from the remote computer "Server01" and returns their SID, profile path, and other details. | ||
.NOTES | ||
This function does not require administrative privileges to access profile information, as it relies on CIM/WMI methods | ||
to retrieve data. It specifically filters out special profiles (such as system profiles) using the "Special=False" filter. | ||
#> | ||
|
||
function Get-SIDProfileInfoFallback | ||
{ | ||
[OutputType([PSCustomObject[]])] | ||
[CmdletBinding()] | ||
param ( | ||
[string]$ComputerName = $env:COMPUTERNAME | ||
) | ||
# Use CIM as a fallback method to get user profile information | ||
$profiles = Get-CimInstance -ClassName Win32_UserProfile -ComputerName $ComputerName -Filter "Special=False" | ||
|
||
$ProfileRegistryItems = foreach ($profile in $profiles) | ||
{ | ||
# Return a PSCustomObject similar to what Get-SIDProfileInfo returns | ||
[PSCustomObject]@{ | ||
SID = $profile.SID | ||
ProfilePath = $profile.LocalPath | ||
ComputerName = $ComputerName | ||
ExistsInRegistry = $true | ||
} | ||
} | ||
|
||
return $ProfileRegistryItems | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<# | ||
.SYNOPSIS | ||
Validates whether a given string follows the correct SID (Security Identifier) format. | ||
.DESCRIPTION | ||
The Validate-SIDFormat function checks if a given string matches the standard SID format. | ||
SIDs typically start with 'S-1-' followed by a series of digits separated by hyphens. | ||
This function returns $true if the SID format is valid and $false if it is not. | ||
.PARAMETER SID | ||
The SID string to validate. This should follow the typical format: 'S-1-' followed by | ||
a series of digits and hyphens. | ||
.OUTPUTS | ||
[bool] | ||
Returns $true if the SID format is valid; otherwise, returns $false. | ||
.EXAMPLE | ||
PS> Validate-SIDFormat -SID 'S-1-5-18' | ||
True | ||
This example checks if the SID 'S-1-5-18' is valid. | ||
.EXAMPLE | ||
PS> Validate-SIDFormat -SID 'Invalid-SID' | ||
WARNING: Invalid SID format encountered: 'Invalid-SID'. | ||
False | ||
This example demonstrates how the function handles an invalid SID format by returning $false | ||
and issuing a warning. | ||
.NOTES | ||
.LINK | ||
https://docs.microsoft.com/en-us/windows/win32/secauthz/security-identifiers | ||
#> | ||
function Validate-SIDFormat | ||
{ | ||
param ( | ||
[OutPutType([bool])] | ||
[CmdletBinding()] | ||
[Parameter(Mandatory = $true)] | ||
[string]$SID | ||
) | ||
|
||
# Regular expression pattern for validating the SID format | ||
$sidPattern = '^S-1-\d+(-\d+)+$' | ||
|
||
if ($SID -notmatch $sidPattern) | ||
{ | ||
Write-Warning "Invalid SID format encountered: '$SID'." | ||
return $false | ||
} | ||
|
||
return $true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Your functions | ||
|
||
|
||
# Check if the current user is an administrator | ||
$windowsIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() | ||
$windowsPrincipal = New-Object Security.Principal.WindowsPrincipal($windowsIdentity) | ||
$isAdmin = $windowsPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | ||
|
||
# Set the environment variable based on whether the user is an admin | ||
if ($isAdmin) | ||
{ | ||
$ENV:WinProfileOps_IsAdmin = $true | ||
} | ||
else | ||
{ | ||
$ENV:WinProfileOps_IsAdmin = $false | ||
} | ||
|
||
Write-Verbose "User is an administrator: $ENV:WinProfileOps_IsAdmin" | ||
|
||
[scriptblock]$SB = { | ||
if (Test-Path Env:\WinProfileOps_IsAdmin) | ||
{ | ||
Remove-Item Env:\WinProfileOps_IsAdmin | ||
Write-Verbose "WinProfileOps: Removed WinProfileOps_IsAdmin environment variable." | ||
} | ||
} | ||
|
||
Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action { | ||
$sb.Invoke() | ||
} | ||
|
||
# Define the OnRemove script block for the module | ||
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { | ||
$sb.Invoke() | ||
} |
144 changes: 144 additions & 0 deletions
144
tests/Unit/Private/Get-SIDProfileInfoFallback.tests.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
BeforeAll { | ||
$script:dscModuleName = "WinProfileOps" | ||
|
||
Import-Module -Name $script:dscModuleName | ||
|
||
$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName | ||
$PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName | ||
$PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName | ||
} | ||
|
||
AfterAll { | ||
$PSDefaultParameterValues.Remove('InModuleScope:ModuleName') | ||
$PSDefaultParameterValues.Remove('Mock:ModuleName') | ||
$PSDefaultParameterValues.Remove('Should:ModuleName') | ||
|
||
# Unload the module being tested so that it doesn't impact any other tests. | ||
Get-Module -Name $script:dscModuleName -All | Remove-Module -Force | ||
} | ||
|
||
Describe 'Get-SIDProfileInfoFallback' -Tag 'Private' { | ||
|
||
Context 'When retrieving user profiles via fallback' { | ||
|
||
BeforeEach { | ||
InModuleScope -ScriptBlock { | ||
# Mock Get-CimInstance to simulate returning non-special profiles | ||
Mock Get-CimInstance { | ||
return @( | ||
[PSCustomObject]@{ SID = 'S-1-5-21-1001'; LocalPath = 'C:\Users\User1' }, | ||
[PSCustomObject]@{ SID = 'S-1-5-21-1002'; LocalPath = 'C:\Users\User2' } | ||
) | ||
} | ||
} | ||
} | ||
|
||
It 'Should return profiles from the local computer' { | ||
$ComputerName = $env:COMPUTERNAME | ||
|
||
# Call the private function within the module scope | ||
$result = InModuleScope -ScriptBlock { | ||
Get-SIDProfileInfoFallback -ComputerName $ComputerName | ||
} | ||
|
||
# Validate the results | ||
$result | Should -HaveCount 2 | ||
$result[0].SID | Should -Be 'S-1-5-21-1001' | ||
$result[0].ProfilePath | Should -Be 'C:\Users\User1' | ||
$result[1].SID | Should -Be 'S-1-5-21-1002' | ||
$result[1].ProfilePath | Should -Be 'C:\Users\User2' | ||
|
||
# Assert that Get-CimInstance was called once | ||
Assert-MockCalled Get-CimInstance -Exactly 1 | ||
} | ||
|
||
It 'Should return profiles from a remote computer' { | ||
$result = InModuleScope -ScriptBlock { | ||
|
||
$ComputerName = 'RemotePC' | ||
|
||
# Call the private function within the module scope | ||
|
||
Get-SIDProfileInfoFallback -ComputerName $ComputerName | ||
} | ||
|
||
# Validate the results | ||
$result | Should -HaveCount 2 | ||
$result[0].SID | Should -Be 'S-1-5-21-1001' | ||
$result[0].ProfilePath | Should -Be 'C:\Users\User1' | ||
$result[1].SID | Should -Be 'S-1-5-21-1002' | ||
$result[1].ProfilePath | Should -Be 'C:\Users\User2' | ||
$result[0].ComputerName | Should -Be 'RemotePC' | ||
$result[1].ComputerName | Should -Be 'RemotePC' | ||
|
||
# Assert that Get-CimInstance was called once | ||
Assert-MockCalled Get-CimInstance -Exactly 1 | ||
} | ||
} | ||
|
||
Context 'When no profiles are returned' { | ||
BeforeEach { | ||
InModuleScope -ScriptBlock { | ||
# Mock Get-CimInstance to return an empty list | ||
Mock Get-CimInstance { | ||
return @() | ||
} | ||
} | ||
} | ||
|
||
It 'Should return an empty result when no profiles are found' { | ||
$ComputerName = $env:COMPUTERNAME | ||
|
||
# Call the private function within the module scope | ||
$result = InModuleScope -ScriptBlock { | ||
Get-SIDProfileInfoFallback -ComputerName $ComputerName | ||
} | ||
|
||
# Validate the result is empty | ||
$result | Should -BeNullOrEmpty | ||
|
||
# Assert that Get-CimInstance was called once | ||
Assert-MockCalled Get-CimInstance -Exactly 1 | ||
} | ||
} | ||
|
||
Context 'When Get-CimInstance throws an error' { | ||
BeforeEach { | ||
InModuleScope -ScriptBlock { | ||
# Mock Get-CimInstance to throw an error | ||
Mock Get-CimInstance { | ||
throw "CIM query failed" | ||
} | ||
|
||
# Mock Write-Error to capture the error | ||
Mock Write-Error | ||
} | ||
} | ||
|
||
It 'Should log an error and return nothing when Get-CimInstance fails' { | ||
$ComputerName = $env:COMPUTERNAME | ||
|
||
# Call the private function within the module scope | ||
$result = InModuleScope -ScriptBlock { | ||
try | ||
{ | ||
Get-SIDProfileInfoFallback -ComputerName $ComputerName | ||
} | ||
catch | ||
{ | ||
Write-Error "Error retrieving profiles via CIM" | ||
} | ||
} | ||
|
||
# The result should be empty | ||
$result | Should -BeNullOrEmpty | ||
|
||
# Assert that Write-Error was called | ||
Assert-MockCalled Write-Error -Exactly 1 | ||
|
||
# Assert that Get-CimInstance was called once | ||
Assert-MockCalled Get-CimInstance -Exactly 1 | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.