PSShareTru.psm1
function Get-STConfig { <# .SYNOPSIS Gets the current config for the module. .DESCRIPTION Gets the current config for the module. This is used to set the default values for the module. .EXAMPLE Get-STConfig #> [CmdletBinding()] param() $script:config } function Get-STDirectory { <# .SYNOPSIS Get directories. Generally broken/useless at this point since it can't list directory contents .DESCRIPTION Can do some basic filtering, but nothing very good. Best to ignore this cmdlet until there is better support for this endpoint. .PARAMETER Path The path to the directory or directory ID to retrieve .PARAMETER Raw Return the raw endpoint results rather than extracting the useful data. #> [CmdletBinding()] param( [string]$Path, [Switch]$Raw ) Write-Warning "This is just broken (error 924661345)......" if (-not $script:config) { Set-STConfig } $param = $script:config.Irm_splat $page_mixin = "page=1,$($script:config.PageSize)" if ($Path -as [int]) { Invoke-RestMethod @param "$($script:config.BaseUri)/api/folders/$Path/" } elseif ($Path) { Invoke-RestMethod @param "$($script:config.BaseUri)/api/folders/?filter[]=name,begins,$($Path -replace ' ', '%20')&$page_mixin" } else { Invoke-RestMethod @param "$($script:config.BaseUri)/api/folders/?$page_mixin" } } function Get-STIpRestriction { <# .SYNOPSIS Retrieve the IP address restrictions in place. Can be restricted to specific user(s). .DESCRIPTION Lists all allowed IP address restrictions that are in place for any number of users. Can be any number of users and will return which rules apply to which users. .PARAMETER UserId The UserId [int[]] to be fetched. Defaults to all users if not specified. Is InputObject for pipelining. .PARAMETER Raw Return the raw endpoint results rather than extracting the useful data. .PARAMETER Page Indicate which page should be returned (default is 1) .PARAMETER PageSize Indicate how many items should be on each page. .EXAMPLE Get-STIpRestriction .EXAMPLE Get-STUser user@foo.com | Get-STIpRestriction | ft .EXAMPLE Get-STUser | ogv -PassThru | Get-STIpRestriction | sort username,start_ip | ft .NOTES General notes #> [CmdletBinding()] param( [Alias("id")] [Parameter( ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true )] [int[]]$UserId, [int]$Page = 1, [int]$PageSize, [switch]$Raw ) begin { # Allows lazy loading of the config by waiting until the first time it is needed. if (-not $script:config) { Set-STConfig } $param = $script:config.Irm_splat $qs = $null } process { $queryString = [System.Web.HttpUtility]::ParseQueryString([string]::Empty) if (-not $PageSize) { $PageSize = $script:config.PageSize } $queryString.Add("page", "$Page,$PageSize") if ($UserId) { Write-Verbose "Selecting specific user with id $UserId" $queryString.Add("filter[]", "user-id,=,$UserId") } else { Write-Verbose "Selecting all users" } if ($queryString.ToString()) { $qs = "?" + $queryString.ToString() } $res = Invoke-RestMethod @param "$($script:config.BaseUri)/api/network_rules/$qs" if ($Raw) { $res } else { foreach ($item in $res.data) { $item.attributes | Select-Object @{n = 'username'; e = { $item.relationships.user.meta.label | Select-Object -First 1 } }, * } } } } function Get-STLog { <# .SYNOPSIS Retrieve the file logs from the server. Can be filtered by IP address, user, command, arguments, or filename. Generally used like tail to watch the logs live. .DESCRIPTION Lists all file logs that are in place. Can be any number of users and will return which entries apply to which users. Filtering can be done by IP range, IP address, file, user, or other arguments. .PARAMETER InputObject Filter critera. Can be IP address, IP address range, Get-STUser object, username, file path, or other "sftp arguments" that may be present .PARAMETER DisableColorize By default, a new log entry is compared to the immediate prior log entry. If the prior one was more than 5 seconds before the current one, the current one will have its timestamp colorized to help indicate the start of the scrollup. You can disable this functionality via -DisableColorize. .PARAMETER DisableWait By default, the cmdlet will continue to retrieve events in realtime until a key is pressed. In order to retrieve the latest logs and immediately return, use -DisableWait. It usually is paired with -Raw .PARAMETER Raw Return the raw endpoint results rather than extracting the useful data. .PARAMETER Page Indicate which page should be returned (default is 1) .PARAMETER PageSize Indicate how many items should be on each page. .PARAMETER Sort Indicate how to sort items on the server side. .EXAMPLE Get-STLog | ft .EXAMPLE Get-STLog bob | ft .EXAMPLE Get-STLog 12.34.56.221 | ogv A really good way to review logs is to use ogv and to sort by time descending. This creates a nice scroll that doesn't require you to move. .EXAMPLE Get-STLog /one .EXAMPLE Get-STLog /one/two/sales.txt .EXAMPLE Get-STLog sales.txt .EXAMPLE Get-STUser bob | Get-STLog | ft View log realtime log entries for the user(s) matching bob. .EXAMPLE Get-STUser | ogv -passthru | Get-STIpRestriction | Get-STLog Interactively select user(s) and then open a live log showing traffic for those allowed IP addresses. #> [CmdletBinding()] param( [Parameter( ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true )] $InputObject, [switch]$DisableColorize, [switch]$DisableWait, [switch]$Raw, $Page = 1, $PageSize = 100, $Sort = "-id" ) begin { # Ensure the global configuration is initialized to avoid redundant checks later. if (-not $script:config) { Set-STConfig } $param = $script:config.Irm_splat $qs = $null $queryString = [System.Web.HttpUtility]::ParseQueryString([string]::Empty) if (-not $PageSize) { $PageSize = $script:config.PageSize } $queryString.Add("page", "$Page,$PageSize") if ($Sort) { $queryString.Add("sort", $Sort) } $qs = "?" + $queryString.ToString() $psrl = Get-PSReadLineOption [int]$id = $null $date = Get-Date $filter = @() } process { $InputObject | ForEach-Object { $filter += $_ } } end { # Get all the IP addresses that will be used for filtering # and split them into a separate array for the IP address filter # We want to convert single IP addresses to the IP address range format for simplicity $ipaddress_regex = '^(?:\d{1,3}\.){3}\d{1,3}$' $ipFilters, $otherFilters = $filter.foreach{ if ($_ -match $ipaddress_regex) { [pscustomobject]@{ start_ip = $_ end_ip = $_ } } else { $_ } }.where({ $_.start_ip -match $ipaddress_regex -and $_.end_ip -match $ipaddress_regex }, "split") # Allow pipelined users from Get-STUser to get filtered with too $otherFilters = $otherFilters.foreach{ if ($username = $_.attributes.username) { $username } else { $_ } } # use a nice regex match for the other filters $otherFilters = $otherFilters -join "|" "IP filters in place: $($ipFilters | ConvertTo-Json -Compress)" | Write-Verbose "Other filters in place: $otherFilters" | Write-Verbose do { $res = Invoke-RestMethod @param "$($script:config.BaseUri)/api/file_log/$qs" # Get 1 less than the first item to avoid large scroll while also allowing the first item to instantly get returned if (-not $id -and $res.data) { $id = [int]$res.data[0].id - 1 } if ($filter) { $res.data = $res.data.where{ $ip = $_.attributes.ip_address -as [version]; ($ipFilters | Where-Object { $ip -ge $_.start_ip -and $ip -le $_.end_ip }) -or $( if ($otherFilters) { $_.attributes.user -match $otherFilters -or $_.attributes.arguments -match $otherFilters -or $_.attributes.filename -match $otherFilters } ) } } if ($Raw) { $res } elseif ($new = $res.data | Where-Object id -GT $id | Sort-Object id) { $out = $new | Select-Object -expand attributes | Select-Object @{n = 'date'; e = { [System.TimeZoneInfo]::ConvertTime( [datetime]$_.date_time.date, ([System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object id -EQ "Eastern Standard Time"), ([System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object id -EQ ([System.TimeZone]::CurrentTimeZone.StandardName)) ) } }, ip_address, user, command, arguments, filename, bytes, status_code, status_message if (-not $DisableColorize) { if ($date.AddSeconds(5) -lt $out[0].date) { $date = $out[0].date $out[0].date = $psrl.CommentColor + $out[0].date.Tostring() + $psrl.DefaultTokenColor } else { $date = $out[0].date } } $out $id = $new[-1].id } if ([console]::KeyAvailable) { $null = while ([console]::KeyAvailable) { [console]::ReadKey($true) } break } } while (-not $DisableWait -and -not (Start-Sleep 1)) } } function Get-STUser { <# .SYNOPSIS Retrieves one or more users. .DESCRIPTION Use -Fields to reduce the returned properties per user. Use -ID to retrieve a specific user. -*Operator, -Sort, and -Fields parameters have an argument completer registered to aid. However, they can be ignored if the API supports alternate data. .PARAMETER Username The Username parameters .PARAMETER UsernameOperator The UsernameOperator parameters .PARAMETER Email The Email parameters .PARAMETER EmailOperator The EmailOperator parameters .PARAMETER Name The Name parameters .PARAMETER NameOperator The NameOperator parameters .PARAMETER Status The Status parameters .PARAMETER StatusOperator The StatusOperator parameters .PARAMETER Comments The Comments parameters .PARAMETER CommentsOperator The CommentsOperator parameters .PARAMETER OtpMethod The OtpMethod parameters .PARAMETER OtpMethodOperator The OtpMethodOperator parameters .PARAMETER IdentityProvider The IdentityProvider parameters .PARAMETER IdentityProviderOperator The IdentityProviderOperator parameters .PARAMETER DateToSuspend The DateToSuspend parameters .PARAMETER DateToSuspendOperator The DateToSuspendOperator parameters .PARAMETER HomeFolder The HomeFolder parameters .PARAMETER HomeFolderOperator The HomeFolderOperator parameters .PARAMETER LastLogin The LastLogin parameters .PARAMETER LastLoginOperator The LastLoginOperator parameters .PARAMETER StorageUsed The StorageUsed parameters .PARAMETER StorageUsedOperator The StorageUsedOperator parameters .PARAMETER LastPwdChange The LastPwdChange parameters .PARAMETER LastPwdChangeOperator The LastPwdChangeOperator parameters .PARAMETER ID The user ID to retrieve. .PARAMETER Fields The array of fields to be returned. Argument completer in place with default return values. Does not seem to work well when specifying a specific user by ID number. .PARAMETER Sort Parameter description .PARAMETER Page Indicate which page should be returned (default is 1) .PARAMETER PageSize Indicate how many items should be on each page. .PARAMETER Raw Return the raw endpoint results rather than extracting the useful data. .EXAMPLE Get-STUser | ogv .EXAMPLE Get-STUser John .EXAMPLE Get-STUser -Email @gallerd.com .EXAMPLE Get-STUser -Username @gallerd.com -UsernameOperator ends .EXAMPLE Get-STUser -ID 10001 .EXAMPLE Get-STUser -Raw | select -expand meta Shows total number of users in the system .EXAMPLE Get-STUser -PageSize 5 Gets the first 5 users from the system .EXAMPLE Get-STUser -PageSize 5 -Page 2 Gets the second set of 5 users from the system #> [CmdletBinding()] param( [string]$Username, [string]$UsernameOperator = "contains", [string]$Email, [string]$EmailOperator = "contains", [string]$Name, [string]$NameOperator = "contains", [string]$Status, [string]$StatusOperator = "contains", [string]$Comments, [string]$CommentsOperator = "contains", [string]$OtpMethod, [string]$OtpMethodOperator = "contains", [string]$IdentityProvider, [string]$IdentityProviderOperator = "contains", [string]$DateToSuspend, [string]$DateToSuspendOperator = "contains", [string]$HomeFolder, [string]$HomeFolderOperator = "contains", [string]$LastLogin, [string]$LastLoginOperator = "contains", [string]$StorageUsed, [string]$StorageUsedOperator = "contains", [string]$LastPwdChange, [string]$LastPwdChangeOperator = "contains", [int]$ID, [string[]]$Fields, [string]$Sort, [int]$Page = 1, [int]$PageSize, [Switch]$Raw ) if (-not $script:config) { Set-STConfig } $param = $script:config.Irm_splat $qs = $null $queryString = [System.Web.HttpUtility]::ParseQueryString([string]::Empty) if ($Fields) { $queryString.Add("fields[user]", $($Fields -join ",")) } $filter = @( "username" "email" "name" "status" "comments" "otp_method" "identity_provider" "date_to_suspend" "home_folder" "last_login" "storage_used" "last_password_change" ) $filter | ForEach-Object { $coded = $_ -replace "_" -replace "password", "pwd" if ($PSBoundParameters[$coded]) { $queryString.Add("filter[]", "$_,$(Get-Variable "${coded}Operator" -ValueOnly),$($PSBoundParameters[$coded])") } } if ($ID) { Write-Verbose "Selecting single user" if ($queryString.ToString()) { if ($Fields) { Write-Warning "This command doesn't work for unknown reasons when it does from the interactive API doc (Error 500961129). Trying it anyway..." } $qs = "?" + $queryString.ToString() } $res = Invoke-RestMethod @param "$($script:config.BaseUri)/api/users/$ID/$qs)" } else { Write-Verbose "Selecting from all users" if (-not $PageSize) { $PageSize = $script:config.PageSize } $queryString.Add("page", "$Page,$PageSize") if ($queryString.ToString()) { $qs = "?" + $queryString.ToString() } $res = Invoke-RestMethod @param "$($script:config.BaseUri)/api/users/$qs" } $queryString.ToString() | Write-Verbose if ($Raw) { $res } else { $res.Data } } Register-ArgumentCompleter -CommandName Get-STUser -ParameterName Fields -ScriptBlock { param( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters ) $fields = @( "username" "email" "name" "comments" "status" "date_suspended" "date_to_suspend" "password_state" "password_expiration_date" "password_expiration_inherit" "password_expiration_days" "last_password_change" "otp_method" "otp_sms_number" "otp_sms_carrier" "otp_sms_gateway" "otp_totp_secret" "ssh_key_authentication_allowed" "storage_used" "identity_provider_uid" "last_login" "home_folder" ) $match = $fields -match "^$wordToComplete" $match | ForEach-Object { New-Object -Type System.Management.Automation.CompletionResult -ArgumentList @( $_ # completionText $_ # listItemText 'ParameterValue' # resultType $_ # toolTip ) } } $completer = { param( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters ) $fields = @( "=" "<>" ">" "<=" ">=" "begins" "ends" "contains" ) $match = $fields -match "^$wordToComplete" $match | ForEach-Object { New-Object -Type System.Management.Automation.CompletionResult -ArgumentList @( $_ # completionText $_ # listItemText 'ParameterValue' # resultType $_ # toolTip ) } } Register-ArgumentCompleter -CommandName Get-STUser -ParameterName UsernameOperator -ScriptBlock $completer Register-ArgumentCompleter -CommandName Get-STUser -ParameterName Sort -ScriptBlock { param( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters ) $fields = @( "id" "-id" "username" "-username" "name" "-name" "status" "-status" "date_to_suspend" "-date_to_suspend" "home_folder" "-home_folder" "last_login" "-last_login" "storage_used" "-storage_used" "last_password_change" "-last_password_change" ) $match = $fields -match "^$wordToComplete" $match | ForEach-Object { New-Object -Type System.Management.Automation.CompletionResult -ArgumentList @( $_ # completionText $_ # listItemText 'ParameterValue' # resultType $_ # toolTip ) } } function Set-STConfig { <# .SYNOPSIS Sets the configuration parameters for this module to use. .DESCRIPTION This command does not reach out to the API server. It only sets the values needed in order for other cmdlets in the module to reach out to the API host. If the BaseURI and ApiKey are stored in ENV variables ($ENV:ST_BASE_URI and $ENV:ST_APIKEY), this cmdlet can be run without any parameters to fully configure the module (or skipped entirely and invoked automatically on first cmdlet invocation). .PARAMETER BaseUri The base URI of the API host. e.g. "https://mycompany.sharetru.com". If the BaseURI and ApiKey are stored in ENV variables ($ENV:ST_BASE_URI and $ENV:ST_APIKEY), this cmdlet can be run without any parameters to fully configure the module (or skipped entirely and invoked automatically on first cmdlet invocation). .PARAMETER ApiKey The API key needed to interact with the HTTPS API. If the BaseURI and ApiKey are stored in ENV variables ($ENV:ST_BASE_URI and $ENV:ST_APIKEY), this cmdlet can be run without any parameters to fully configure the module (or skipped entirely and invoked automatically on first cmdlet invocation). .PARAMETER PageSize Sets the default PageSize for cmdlets in this module to use. .PARAMETER Passthru Return the config object for further review or manipulation. .EXAMPLE Set-STConfig .NOTES General notes #> [CmdletBinding(SupportsShouldProcess)] param( $BaseUri, $ApiKey, $PageSize = 20, [switch]$Passthru ) if ($PSCmdlet.ShouldProcess("PSShareTru", "Nothing outside of module scope")) {} $script:config = @{ BaseUri = $ENV:ST_BASE_URI ApiKey = $ENV:ST_APIKEY PageSize = $PageSize } if ($BaseUri) { $script:config.BaseUri = $BaseUri } if ($ApiKey) { $script:config.ApiKey = $ApiKey } $script:config.Irm_splat = @{ Headers = @{ "X-API-KEY" = $script:config.ApiKey Accept = "application/vnd.api+json" } ContentType = "application/json" } if ($Passthru) { $script:config } } |