Get the Data values from the registry using powershell - powershell

I am trying to add an application in 'DisallowRun' registry key to avoid running application to specific users. Need to add the application if not exist. Consider 'TestApp3.exe' in this case.
Used below query to get the list of items in the key. It is giving Name(Key Name), Property(Name Value : Data Value)
Get-Item -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun"
Output
Name Property
---- --------
DisallowRun 1 : TestApp1.exe
DisallowRun 2 : TestApp2.exe
DisallowRun 3 : TestApp3.exe
DisallowRun 4 : TestApp4.exe
When i use .Property in the code, getting only Name Values and not Data Values
(Get-Item -Path "Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun").Property
Output
1
2
3
4
If i get only the Data Values (similar to below) then i could have use contains function to check the specific application is already available or not. Please help me to get only Data Value or is there anyway to check the application is exist in the registry key.
TestApp1.exe
TestApp2.exe
TestApp3.exe
TestApp4.exe

Try this out.
(Get-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun).PSObject.Properties | Where-Object {
$_.Name -notmatch "^PS"
} | Select-Object -ExpandProperty Value

Try Get-ItemProperty -Path Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun

Related

Is there a way to put a counter column when doing Get commands in PowerShell?

I need to extract a Get command results into a CSV. The order column should be automatically generated upon a call and give each object its counter upon its appearance in the list. Would this be possible?
For example, when I'd do something like
Get-VMHost | Select #{N="Order";E={$suborder++}}, Name, Version, Build | Export-Csv -path .\smth.csv
I would like to get a result like
Order Name Version Build
----- ---- ------- -----
1 servername1 1.1.1 11111111
2 servername2 1.1.1 11111111
3 servername3 1.1.1 11111111
Would this be possible without using an array?
There are two problems with the current approach:
Unary ++ doesn't output anything by default
Select-Object runs property expressions in their own scope, so you're not actually updating $suborder, you're creating a new local variable every time.
The first problem can be solved by wrapping the operation in the grouping operator (...):
... | Select #{N="Order";E={($suborder++)}}, ...
The second problem can be solved by obtaining a reference to an object that exposes the suborder value as a property.
You can either use a hashtable or a custom object to "host" the counter:
$counter = #{ suborder = 1 }
... | Select #{N="Order";E={($counter['suborder']++)}}
... or you can make PowerShell wrap the original variable in a PSRef-wrapper by using the [ref] keyword:
$suborder = 1
... | Select #{N="Order";E={(([ref]$suborder).Value++)}}

How to delete previous database snapshot using regex?

We are restoring a database called Cube1 as "snapshots" using below command.
$CUBE = "$CUBE-Snapshot-$dateStamp"
Restore-ASDatabase -Server $Target_Server -RestoreFile $BFile -Name $CUBE -Security:$SecurityChoice -AllowOverwrite -ErrorAction Stop
However, this is supposed to run weekly indefinitely and our server memory capacity will be diminished leading to performance issues eventually, which we don't want.
Therefore, I'd like to delete existing snapshots, so ultimate result would be something like this (1 snapshot only weekly):
I tried the following:
Import-Module sqlserver
$AnalysisServer = New-Object Microsoft.AnalysisServices.Server
$AnalysisServer.connect("$Target_Server")
$AnalysisServer.Databases["*$CUBE-Snapshot*"].Drop()
and the drop operation failed.
You cannot call a method on a null-valued expression.
When specifying manually the snapshot name:
$AnalysisServer.Databases["Cube1-Snapshot-05-30-2021-0314PM"].Drop()
The drop operation succeeds.
I suppose I need to use some sort of regex then since wildcards didn't seem to work for the name, so how do I accomplish that?
Using [...] to index into the .DataBases collections corresponds to the parameterized .Item[] property, which supports (a) targeting a database by numerical index or (b) by verbatim name - using patterns to match database names is not supported.
Therefore, you need to filter the database collection explicitly, which you can do with the .Where() array method, combined with member-access enumeration, which allows you to call the .Drop() method on every matching database:
$AnalysisServer.Databases.Where({ $_.Name -like "*$CUBE-Snapshot*" }).Drop()
Note: If no databases match, the above will generate a statement-terminating error; to avoid that, use a two-step approach:
$matchingDbs = $AnalysisServer.Databases.Where({ $_.Name -like "*$CUBE-Snapshot*" })
if ($matchingDbs) { $matchingDbs.Drop() }
To delete all snapshots except the most recent one, based on the naming convention shown in the question:
$matchingDbs = $AnalysisServer.Databases.Where({ $_.Name -like "*$CUBE-Snapshot*" })
if ($matchingDbs.Count -ge 2) {
($matchingDbs | Sort-Object Name -Descending | Select-Object -Skip 1).Drop()
}

fetch particular column in PowerShell

I am creating a PowerShell Script wherein I have a csv file which consist of few parameters wherein there is a parameter called as status .The ask is whenever the status is Fail ,I want to get the corresponding row. I am using Import-Csv cmdlet in order to fetch the csv file and checking the status if the status is fail or not and based on that I am fetching the corresponding details using the split function but when I am using the split method it is giving me error as
Method invocation failed because
[System.Management.Automation.PSCustomObject] does not contain a
method named 'split'.
Using the below code
$Report=(Import-Csv "C:\Users\Documents\Optim_Config_Report_20210216170900.csv")
foreach($i in $Report)
{
if($i.Status -eq "Fail")
{
$RULE_ID= $i.split(',')[0]
Write-output $RULE_ID
}
}
Can someone please help me how can I get the corresponding Row details for which the Status is fail?
Report is something like this in a csv format
Rule,Id,Category,Sub_Category,System_Value,Risk,Status
1,Operations,Access,Login,High,Pass
2,Operations,Logging,AccessControl,Medium,Pass
3,Operations,encryptions,certificate,High,Fail,
4,Security,Encryption,protcolo,High,Fail
Thanks in Advance!
When you Import-CSV, you are creating an array of [PSCustomObject]s, each of which has properties corresponding to the names of the columns in the CSV. For your example, those properties will be Rule, ID, Category, Sub_Category, System_Value, Risk, and Status.
It is not clear from your example what information you wish to report in the event of a status of Fail, but all you need to do is reference the properties that contain that information - for example, if I wanted to report the Category and Sub_Category, I might use
...
if ($i.status -eq "Fail") {
Write-Host $i.Category, $i.Sub_Category
}
...
Which would, for your sample data, output
encryptions certificate
Encryption protcolo
For a CSV file named "test.csv" with content like this:
"Rule","Id","Category","Sub_Category","System_Value","Risk","Status"
1,Operations,Access,Login,1,High,Pass
2,Operations,Logging,AccessControl,1,Medium,Pass
3,Operations,encryptions,certificate,1,High,Fail
4,Security,Encryption,protcolo,1,High,Fail
This script:
Import-Csv -Path ./test.csv | Where-Object Status -eq Fail | Format-Table
Returns:
Rule Id Category Sub_Category System_Value Risk Status
---- -- -------- ------------ ------------ ---- ------
3 Operations encryptions certificate 1 High Fail
4 Security Encryption protcolo 1 High Fail

Export-Csv MIM FIM PowerShell Issue

I was asked to retrieve a .csv list with all users that registered to the FIM portal. I did some searching until I stumbled accross this script:
set-variable -name URI -value "http://localhost:5725/resourcemanagementservice' " -option constant
set-variable -name CSV -value "RegistredResetPassUsers.csv" -option constant
clear
If(#(Get-PSSnapin | Where-Object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {Add-PSSnapin FIMAutomation}
$WFDFilter = "/WorkflowDefinition[DisplayName='Password Reset AuthN Workflow']"
$curObjectWFD = export-fimconfig -uri $URI –onlyBaseResources -customconfig ($WFDFilter) -ErrorVariable Err -ErrorAction SilentlyContinue
$WFDObjectID = (($curObjectWFD.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "ObjectID"}).value).split(":")[2]
$Filter = "/Person[AuthNWFRegistered = '$WFDObjectID']"
$curObject = export-fimconfig -uri $URI –onlyBaseResources -customconfig ($Filter) -ErrorVariable Err -ErrorAction SilentlyContinue
[array]$users = $null
foreach($Object in $curObject)
{
$ResetPass = New-Object PSObject
$UserDisplayName = (($Object.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "DisplayName"}).Value)
$ResetPass | Add-Member NoteProperty "DisplayName" $UserDisplayName
$Users += $ResetPass
}
$users | export-csv -path $CSV
The script works without errors except that the actual list that it exports only contains my display name. I've been trying to figure out why its not exporting the complete list of all users and only shows my name, but I haven't been able to figure it out so I was wondering if any one could help me shed some light into this issue.
Thanks again for any help you guys can provide!
No experience with this snapin/product, but seeing as the code fundamentally works (it returns your object) this could be a permissions issue. You may not be able to read the other user objects, so they're not being exposed to you.
If you can view them in a UI console of some kind, then check for separate permissions related to API actions, and ensure you have access that way.
Another course of action may be to run the code line by line and see what results you receive from each line, to make sure you get what you're expecting.
Try replacing:
[array]$users = $null
With:
$users = #()
This is likely due to permission setup.
By default you have a permissions to see your own attributes.
There is likely some Management Policy Rule setup so user accounts in a specific Set can read AuthNWFRegistered attribute of other users to support for troubleshooting and customer support.
You will need to use one of the options:
Add the account used for this script into the Set that delegates out this Read permission already
or
Create a separate MPR for this particular reporting (this is what I would recommend) that Grants permissions for a specific user account to read AuthNWFRegistered attribute.
Also make sure there is really only one Workflow that is associated with user registration. If there are multiple, you'd want to target Set with all register Workflows in your XPath filter instead of particular Workflow name.
On a separate note - while FIMAutomation is sometimes necessary snapin to use with standard tooling, for your custom work I strongly suggest to use Lithnet's LithnetRMA PowerShell module (https://github.com/lithnet/resourcemanagement-powershell).
You will be much more productive with it and most of the operations will be without boilerplate code FIMAutomation needs. This will be your code using LithnetRMA.
Set-ResourceManagementClient -BaseAddress 'http://localhost:5725/resourcemanagementservice'
$scope = Search-Resources -XPath "/Person[AuthNWFRegistered = /WorkflowDefinition[DisplayName='Password Reset AuthN Workflow']]" -ExpectedObjectType Person
$scope | select DisplayName | Export-Csv 'RegistredResetPassUsers.csv' -Encoding Unicode

How can I summarize an object the same way Format-List does?

For example, looking at a processes threads shows something like this:
PS C:\> (Get-Process)[0] | Format-List -Property Threads
Threads : {1548, 1600, 15940, 13996}
But if you actually grab that property directly, it looks like this:
PS C:\> (Get-Process)[0].Threads
BasePriority : 8
CurrentPriority : 9
Id : 1548
IdealProcessor :
PriorityBoostEnabled :
PriorityLevel :
PrivilegedProcessorTime :
StartAddress : 8790537024736
StartTime :
ThreadState : Wait
TotalProcessorTime :
UserProcessorTime :
WaitReason : UserRequest
ProcessorAffinity :
Site :
Container :
BasePriority : 8
... etc
Format list obviously has a method to summarize objects intelligently. It took a list of objects, pulled out a representative property from each one, and displayed it as a short array. I cannot find a method or cmdlet that allows me to summarize an collection of objects in the same manner.
I want to be able to pass an arbitrary collection of objects to a method and have it summarize. This is used when listing email addresses in Exchange objects, listing groups in AD objects, and many other places... I doubt these are all special cases.
To expand (after learning more from #JoelSmith's comments):
.NET Objects have formatting definitions that are used by Powershell when formatting output. Additional details are available using help about_Format.ps1xml[1]. These definitions are generic and can be accessed by any command, but by default there are no functions in Powershell to directly retrieve the output of an object property directly as it would be displayed in Format-List.
One hackish workaround is to split and strip the output like so:
(Get-Mailbox user | Format-List -Property Languages | Out-String).Split(':')[1].Trim()
# => {en-US,fr-CA}
However this method is extremely fragile, and will fail when the output spans multiple lines or contains a colon in the output:
(Get-Mailbox user | Format-List -Property EmailAddresses | Out-String).Split(':')[1].Trim()
# => {smtp
What is needed is a method that reads the formatting definition defined for the object and retrieves it directly, then use it to output the desired string. I have failed to find any example online.
You can use the
PSStandardMembers.DefaultDisplayProperty
and
PSStandardMembers.DefaultDisplayPropertySet
properties of your objects to determine the default properties that should be displayed for each type. You can read more about it here. We've run into a similar problem recently in our like PowerShell project. You can find this discussion we've had helpful. There are some subtle differences between PS v2 and v3 which we debate on that thread.
Usually .ToString() works but sometimes they forget to implement that method.
(Get-Process)[0] | %{$_.Threads.Id}
EDIT: to answer your comment below
(Get-Process)[0] | Format-List -Property Threads | Out-String
Unfortunately not all cmdlets are the same.
Are you looking for something like this?
(Get-Process)[0].Threads | Format-Table -Property ID -AutoSize
Id
--
13060
13064
13068
13072
13076
13080
13084
This needs to be customized for each cmdlet depending on what the output is and what fields you need. The reason it doesn't work with just (Get-Process)[0] | Format-Table -Property Threads -AutoSize is because Threads returns thread-objects, and an array of objects are displayed like your first sample (string-presentation of your objects in a collection { .. }) .
Here's what I can tell so far:
The Id property is the default display property for a thread object (System.Diagnostics.ProcessThread).
I couldn't find any tracks of this in any of PowerShell's type files but I can change the way Format-* display threads (requires PowerShell 3.0).
By default the format cmdlets prints the Id value of each thread object:
Threads : {1548, 1600, 15940, 13996}
Formatting cmdlets checks the value of the $FormatEnumerationLimit variable (default is 4) to decide how to format the object.
If the result is one object (scalar) only it will print as:
Threads : 1548
If it's a collection of items and the collection count is up to the value of $FormatEnumerationLimit (4) it will display as:
Threads : {1548, 1600, 15940, 13996}
A count greater than $FormatEnumerationLimit will look like (... indicates that there are more objects):
Threads : {1548, 1600, 15940, 13996...}
I can tell Id is the default property in use because I can change it to another property and see its value reflecting in the output.
For example, Here I'm setting the ThreadState as the default display property:
PS> Update-TypeData -TypeName System.Diagnostics.ProcessThread -DefaultDisplayProperty ThreadState -Force
PS> (Get-Process)[0] | Format-List -Property Threads
Threads : {Wait, Wait, Wait, Wait...}
# revert back
PS> Update-TypeData -TypeName System.Diagnostics.ProcessThread -DefaultDisplayProperty Id -Force
Hope that helps