Commands/Effects/Import-OBSEffect.ps1
function Import-OBSEffect { <# .SYNOPSIS Imports Effects .DESCRIPTION Imports obs-powershell effects .EXAMPLE Import-OBSEffect -Path (Get-Module obs-powershell) .LINK Get-OBSEffect #> param( # The source location of the effect. # This can be a string, file, directory, command, or module. [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias( 'FromPath', 'FromModule', 'FromScript', 'FromFunction', 'FullName', 'Path', 'Source' )] [ValidateScript({ $validTypeList = [System.String],[System.IO.FileInfo],[System.IO.DirectoryInfo],[System.Management.Automation.CommandInfo],[System.Management.Automation.PSModuleInfo] $thisType = $_.GetType() $IsTypeOk = $(@( foreach ($validType in $validTypeList) { if ($_ -as $validType) { $true;break } })) if (-not $isTypeOk) { throw "Unexpected type '$(@($thisType)[0])'. Must be 'string','System.IO.FileInfo','System.IO.DirectoryInfo','System.Management.Automation.CommandInfo','psmoduleinfo'." } return $true })] $From ) begin { if (-not $script:OBSFX) { $script:OBSFX = [Ordered]@{} } $newEffects = @() $obsEffectsPattern = [Regex]::new(' (?> ^OBS.(?>fx|effects?)\p{P} | [\p{P}-[-]]OBS\.(?>fx|effects?)$ | \p{P}OBS.(?>fx|effects?)\.(?>ps1|json)$ ) ','IgnoreCase,IgnorePatternWhitespace') } process { # Since -From can be many things, but a metric has to be a command, # the purpose of this function is to essentially resolve many things to a command, # and then cache that command. # If -From was a string if ($From -is [string]) { # It could be a module, so check those first. :ResolveFromString do { foreach ($loadedModule in @(Get-Module)) { # If we find the module, don't try to resolve -From as a path if ($loadedModule.Name -eq $from) { # (just set -From again and let the function continue) $from = $fromModule = $loadedModule;break ResolveFromString } } # If we think from was a path $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($from) # attempt to resolve it if ($resolvedPath) { $from = Get-Item -LiteralPath $resolvedPath } } while ($false) } # If -From is a module if ($from -is [Management.Automation.PSModuleInfo]) { # recursively call ourselves with all matching commands @($from.ExportedCommands.Values) -match $obsEffectsPattern | Import-OBSEffect # then, make -From a directory if ($from.Path) { $from = Get-Item ($from.Path | Split-Path) -ErrorAction SilentlyContinue } } # If -From is a directory if ($from -is [IO.DirectoryInfo]) { $FromDirectory = $from # recursively call ourselves with all matching scripts Get-ChildItem -LiteralPath $from.FullName -Recurse -File | Where-Object Name -match '\.obs\.(?>fx|effects?).(?>ps1|json)$' | Import-OBSEffect return } # If -From is a file if ($from -is [IO.FileInfo]) { # and it matches the naming convention if ($from.Name -notmatch '\.obs\.(?>fx|effects?).(?>ps1|json)$') { return } # make -From a command. $from = $ExecutionContext.SessionState.InvokeCommand.GetCommand($from.FullName, 'ExternalScript,Application') } # If -From is a command if ($from -is [Management.Automation.CommandInfo]) { # decorate the command if ($from.pstypenames -notcontains 'OBS.PowerShell.Effect') { $from.pstypenames.insert(0,'OBS.PowerShell.Effect') } if ($from -is [Management.Automation.ApplicationInfo]) { $effectName = $from.Name -replace '\.obs\.(?>fx|effects?).(?>ps1|json)$' $newEffect = [PSCustomObject][Ordered]@{ PSTypeName = 'OBS.PowerShell.Effect' Messages = Get-Content -Raw -Path $From.Source | ConvertFrom-Json EffectName = $effectName TypeName = $TypeName } $script:OBSFX[$effectName] = $newEffect $newEffects += $newEffect $newEffect } else { if ($from.pstypenames -notcontains 'OBS.PowerShell.Effect.Command') { $from.pstypenames.insert(0,'OBS.PowerShell.Effect.Command') } # and add it to our list of new metrics $newEffects+= $from $script:OBSFX[$from.EffectName] = $from $from } } } } |