I'm trying to find all the values recursively that contains this sub-string in it name : "~fr-FR~".
$registry = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackageDetect\" -Recurse
Foreach($a in $registry) {
($a | Get-ItemProperty).Psobject.Properties |
Where-Object { $_.Name -like '*~fr-FR~*' }
}
At this point I can retrieve all the values filtered recursively. Pasted below is example of one of the results:
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 3
TypeNameOfValue : System.Int32
Name : Microsoft-Windows-GroupPolicy-ClientTools-Package~31bf3856ad364e35~amd64~fr-FR~10.0.17134.1
IsInstance : True
How do I remove the sub-string?
Related
The following code gives me the default app pool, converted to string. When I pass this variable
$appPoolName = Get-IISAppPool | Select-Object Name | Where-Object {$_.Name -like "Default" } | Out-String
(Get-IISAppPool $appPoolName).processmodel.username
I get the following error
Why not just do this:
$appPoolName = (Get-IISAppPool | Where-Object Name -Match 'Default').Name
(Get-IISAppPool $appPoolName).processmodel
# Results
<#
IdentityType : ApplicationPoolIdentity
IdleTimeout : 00:20:00
IdleTimeoutAction : Terminate
LoadUserProfile : True
MaxProcesses : 1
PingingEnabled : True
PingInterval : 00:00:30
PingResponseTime : 00:01:30
Password :
ShutdownTimeLimit : 00:01:30
StartupTimeLimit : 00:01:30
UserName :
...
#>
How can I search all the properties of a single object for a given string?
Say I have the following command output:
get-aduser jtest -properties *
DistinguishedName : CN=jtest,CN=Users,DC=confederationc,DC=on,DC=ca
Enabled : True
GivenName : Justus
Name : jtest
ObjectClass : user
ObjectGUID : f4d31d45-0505-433e-9442-152419e75d26
SamAccountName : jtest
SID : S-1-5-21-2138664166-620177494-281947949-184391
Surname : Test
UserPrincipalName : jtest#confederationcollege.ca
...output truncated
How can I search for any property that contains the string "jtest"?
I feel like I must be missing something obvious.
There's always findstr (case insensitive), but the result is only text. This is a common question.
get-aduser jtest | findstr /i jtest
Name : jtest
SamAccountName : jtest
UserPrincipalName : jtest#confederationcollege.ca
This doesn't work in all cases, but it does for registry entries. This can match against most property names or values. It depends on what "$_" converts to as a string. Generic pscustomobjects work. It won't work for the get-aduser example (the object converts to a distinguishedname string).
get-itemproperty hkcu:\key1 | ? { $_ -match 'foo' } # or 'emspace'
value1 : 17
emspace : foo bar
refcount : {255, 255}
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\key1
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER
PSChildName : key1
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry
get-itemproperty hkcu:\key1 | % { "$_" } # showing string conversion
#{value1=17; emspace=foo bar; refcount=System.Byte[]; PSPath=Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\key1; PSParentPath=Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER; PSChildName=key1; PSDrive=HKCU; PSProvider=Microsoft.PowerShell.Core\Registry}
You can use the hidden psobject memberset on any object in PowerShell to access its underlying properties programmatically:
foreach($user in Get-ADUser jtest){
foreach($property in $user.psobject.Properties){
if($_.Value -like '*jtest*'){
"Property '$($_.Name)' has value '$($_.Value)'"
}
}
}
passing by value or reference : powershell
more information :
PSVersion 5.1.19041.906
All files can be found here : [*]https://drive.google.com/drive/folders/1Ya0Xyxewgo6FtUHVbGqSASqXOFSlXvbR?usp=sharing
I would like to try to pass an object by reference, variable. In this object I would like to pass a bunch of information (containing different other variables/data).
Sometimes there's a need to return it back (one variable), by return $menuObjts.
At paragraphs 'INFO' are $menuObjts and $menuObjts[‘MENUS’] shown.
More information about these object I have tried to figure it out by gettype().fullname.
REMARK : in the code here I've used $global: for allowing to ACCESS and CHANGE the variable and be able to make a screenshot and use it for test purpose.
So my problem is to ACCESS and CHANCE values in $menuObjts[‘MENUS’], which is a part, element of $menuObjts.
Thanks to #Santiago Squarzon for his patience and quick reaction.
The idea is to create dynamically menus from the CSV file (what works) and calls the selected functions by name - $menus_.FUNCTION which are retrieved.
But now I would like to extend it and be able to create multi sub menus.
There are two seperate MENU_GRP elements :
$menuObjts.MENU_GRP
-- contains info about the current/active/selected one
($menuObjts.**MENUS** | Where-Object {[int]**$($_).MENU_GRP** -eq ...
-- $menuObjts.MENUS : contains all posible menus (CSV)
So I import a range menu-items by a CSV file.
So these $menus_ are added to $menuObjts.MENUS / $menuObjts[‘MENUS’]
There are other features in $menus_ such as MENU, PARENT, MENU_GRP, MENU_IDX, MENU_OFFSET, MENU_SEL_TYPE, nrElems, FUNCTION, info, status , SEL, RESTART, STOP
$global:menus_ = Import-Csv -Delimiter "," $($curPath)
$menuGRP_ = 0 # 0 - MAIN
$menus_.MENU
$nrRestarts = #($menus_ | Where-Object { [int]$_.RESTART -eq 1 -and [int]$_.MENU_GRP -eq 0 }).Count
write-host (" info : - nrRestarts: {0}" -f ($nrRestarts))
# SET : values in one object : $menuObjts
$global:menuObjts =[ordered]#{
MENUS = $menus_;
MENU_GRP = $menuGRP_;
MENU_SEL_TYPE = $null;
MENU_OFFSET = $null;
nrElems = $null;
sel_input = $null;
MENU_IDX = $null}
$menuObjts.MENUS?MENU_GRP = 0 or $menuObjts.MENUS?MENU_GRP = 6
$menuObjts.MENUS?MENU_OFFSET = -1 or $menuObjts.MENUS?MENU_OFFSET = 12
$menuObjts.MENUS?nrElems = 13 or $menuObjts.MENUS?nrElems = 4
$menuObjts.MENUS ? - ? because I don't know how to retrieve the underlying object and their features/data
So my problem is how to retrieve each element of $menus_ in $menuObjts.MENUS again.
The idea is that via one variable, the next one will be calculated ([*]see function updateMenuObjtsInfo )
So my question is how can I see by type, how to get the wanted data ...
information of variables/object Get-Variable
gettype()
$menuObjts
$menuObjts.MENUS
$menuObjts.MENUS | select -first 1
These are a few things I want to achieve, but this doesn't work proper ($_).MENU_GRP
$1stElementGrp_ = $($menus_ | Where { [int]$($_).MENU_GRP -eq $menuObjts.MENU_GRP }| Select -First 1 )
$menuOFFSET_ = $($1stElementGrp_).MENU_OFFSET
$menuNrElems_ = $($1stElementGrp_).nrElems
##### where $($menuObjts.MENUS).MENU_GRP -eq $menuObjts.MENU_GRP -> .MENU_OFFSET
$menuObjts.MENU_OFFSET = $($menuObjts.MENUS | Where-Object { [int]$($_).MENU_GRP -eq $menuObjts.MENU_GRP}| Select -First 1 ).MENU_OFFSET
$menuObjts.nrElems = #($menuObjts.MENUS | Where-Object { [int]$($_).MENU_GRP -eq $menuObjts.MENU_GRP -and [int]$($_).SEL -eq 1}).Count
Another idea … was adding methods, but I’m struggling with my (little) knowledge of Powershell.
(based on 4 Ways to Create PowerShell Objects | RidiCurious.com )
$menuObjts | Add-Member -MemberType ScriptMethod -Name "getMENUS_RESTART" -Value $( this.MENUS | Where-Object { [int]$_.RESTART -eq 1 -and [int]$_.MENU_GRP -eq $menuGRP_ })
INFO - $menuObjts :
Name Value
---- -----
MENUS {#{MENU;PARENT;MENU_GRP;MENU_IDX;MENU_OFFSET;MENU_SEL_TYPE;nrElems;FUNCTION;info;status;SEL;RESTART;STOP=typeInstallation;LICENSE;0;0;-1;0;13;f1;Windows-Defende...
MENU_GRP 0
MENU_SEL_TYPE
MENU_OFFSET
nrElems
sel_input
MENU_IDX
INFO - $menuObjts.MENUS :
MENU;PARENT;MENU_GRP;MENU_IDX;MENU_OFFSET;MENU_SEL_TYPE;nrElems;FUNCTION;info;status;SEL;RESTART;STOP
-----------------------------------------------------------------------------------------------------
typeInstallation;LICENSE;0;0;-1;0;13;f1;Windows-Defender has to be uninstalled
activate;;0;1;-1;0;13;f2;Windows has to be upgraded if working with an EVALUATION prod key;-1;0;0;0
NAME;HOST;0;2;-1;0;13;f3;F-SEC has to be configured as an isolated machine on the CSI server;-1;0;0;0
IP;;0;3;-1;0;13;f4;disable default Windows NTP service;-1;0;1;0
routes;;0;4;-1;0;13;f5;disable default Windows NTP service;-1;0;0;0
users;;0;5;-1;0;13;f6;disable default Windows NTP service;-1;0;0;0
ANTI VIRUS;SERVICEs;0;6;-1;0;13;f7;disable default Windows NTP service;-1;0;0;0
NTP;;0;7;-1;0;13;f8;;-1;0;0;0
MEINBERG;;0;8;-1;0;13;f9;;-1;0;0;0
addPATH;postgres;0;9;-1;0;13;f10;;-1;0;0;0
check;after CSI;0;10;-1;0;13;f11;;-1;0;0;0
execute;;0;11;-1;0;13;f12;;-1;0;0;1
quite;;0;12;-1;0;13;f13;;-1;0;0;1
WINDOWS DEFENDER;ANTI VIRUS;6;13;12;1;4;f14;;-1;0;0;0
F-SEC;;6;14;12;1;4;f15;;-1;0;0;0
execute;;6;15;12;1;4;f16;;-1;0;0;1
quite;;6;16;12;1;4;f17;;-1;0;0;1
Additional information [2021/05/04]
PS C:\Users\Administrator> $menuObjts.MENUS | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
FUNCTION NoteProperty string FUNCTION=f1
info NoteProperty string info=Windows-Defender has to be uninstalled, before installing an other anti-virus program
MENU NoteProperty string MENU=typeInstallation
MENU_GRP NoteProperty string MENU_GRP=0
MENU_IDX NoteProperty string MENU_IDX=0
MENU_OFFSET NoteProperty string MENU_OFFSET=-1
...
PS C:\Users\Administrator> $menuObjts.MENUS
MENU : typeInstallation
PARENT : LICENSE
MENU_GRP : 0
MENU_IDX : 0
MENU_OFFSET : -1
MENU_SEL-TYPE :
nrElems : 13
FUNCTION : f1
info : Windows-Defender has ...
status : -1
SEL : 0
RESTART : 1
STOP :
MENU : activate
PARENT :
MENU_GRP : 0
...
I have the impression that $menus_ is added as a 'value' instead as an object to $menuObjts - Value : {#{MENU=
PS C:\Users\Administrator> $menuObjts.MENUS.PSobject.Properties
ReferencedMemberName : Length
ConversionType :
MemberType : AliasProperty
TypeNameOfValue : System.Int32
IsSettable : False
IsGettable : True
Value : 17
Name : Count
IsInstance : False
MemberType : Property
Value : 17
IsSettable : False
IsGettable : True
TypeNameOfValue : System.Int32
Name : Length
IsInstance : True
...
MemberType : Property
Value : {#{MENU=typeInstallation; PARENT=LICENSE; MENU_GRP=0; MENU_IDX=0; MENU_OFFSET=-1; MENU_SEL-TYPE=; nrElems=13;FUNCTION=f1; info=Windows-Defender has to be uninstalled, before installing an other anti-virus program;status=-1; SEL=0; RESTART=1; STOP=},
#{MENU=activate; PARENT=; MENU_GRP=0; MENU_IDX=1; MENU_OFFSET=-1; MENU_SEL-TYPE=; nrElems=13; FUNCTION=f2; info=Windows has to be upgraded if working with an EVALUATION prod key;status=-1; SEL=0; RESTART=0; STOP=},
#{MENU=NAME; PARENT=HOST; MENU_GRP=0; MENU_IDX=2; MENU_OFFSET=-1;MENU_SEL-TYPE=; nrElems=13; FUNCTION=f3; info=F-SEC has to be configured as an isolated machine on the CSI server;status=-1; SEL=0; RESTART=0; STOP=},
#{MENU=IP; PARENT=; MENU_GRP=0; MENU_IDX=3; MENU_OFFSET=-1; MENU_SEL-TYPE=;nrElems=13; FUNCTION=f4; info=disable default Windows NTP service; status=-1; SEL=0; RESTART=1; STOP=}...}
IsSettable : False
IsGettable : True
TypeNameOfValue : System.Object
Name : SyncRoot
IsInstance : True
...
First of all, I would recommend a good read on: Where-Object, about_Arrays and this good article on PS Objects
# Storing the CSV in the $csv var
$csv = #'
MENU;PARENT;MENU_GRP;MENU_IDX;MENU_OFFSET;MENU_SEL_TYPE;nrElems;FUNCTION;info;status;SEL;RESTART;STOP
typeInstallation;LICENSE;0;0;-1;0;13;f1;Windows-Defender has to be uninstalled
activate;;0;1;-1;0;13;f2;Windows has to be upgraded if working with an EVALUATION prod key;-1;0;0;0
NAME;HOST;0;2;-1;0;13;f3;F-SEC has to be configured as an isolated machine on the CSI server;-1;0;0;0
IP;;0;3;-1;0;13;f4;disable default Windows NTP service;-1;0;1;0
routes;;0;4;-1;0;13;f5;disable default Windows NTP service;-1;0;0;0
users;;0;5;-1;0;13;f6;disable default Windows NTP service;-1;0;0;0
ANTI VIRUS;SERVICEs;0;6;-1;0;13;f7;disable default Windows NTP service;-1;0;0;0
NTP;;0;7;-1;0;13;f8;;-1;0;0;0
MEINBERG;;0;8;-1;0;13;f9;;-1;0;0;0
addPATH;postgres;0;9;-1;0;13;f10;;-1;0;0;0
check;after CSI;0;10;-1;0;13;f11;;-1;0;0;0
execute;;0;11;-1;0;13;f12;;-1;0;0;1
quite;;0;12;-1;0;13;f13;;-1;0;0;1
WINDOWS DEFENDER;ANTI VIRUS;6;13;12;1;4;f14;;-1;0;0;0
F-SEC;;6;14;12;1;4;f15;;-1;0;0;0
execute;;6;15;12;1;4;f16;;-1;0;0;1
quite;;6;16;12;1;4;f17;;-1;0;0;1
'#|convertfrom-csv -Delimiter ';'
Get the first element of the array
$1stElementGrp_ = $csv[0] # Like this
$1stElementGrp_ = $csv | Select-Object -First 1 # Or Like this
Get the value of the property MENU_OFFSET and nrElems of the variable $1stElementGrp_
$menuOFFSET_ = $1stElementGrp_.MENU_OFFSET # $menuOFFSET_ returns -1
$menuNrElems_ = $1stElementGrp_.nrElems # $menuNrElems_ returns 13
Not sure what you're trying filter here
# $menuObjts.MENU_OFFSET = ($menuObjts.MENUS | Where-Object {
# [int]$($_).MENU_GRP -eq $menuObjts.MENU_GRP
# }| Select -First 1).MENU_OFFSET
#
# $menuObjts.nrElems = #($menuObjts.MENUS | Where-Object {
# [int]$($_).MENU_GRP -eq $menuObjts.MENU_GRP -and [int]$($_).SEL -eq 1}).Count
# }
Example: If you want to filter all the rows where MENU_OFFSET = -1
$csv | Where-Object {$_.MENU_OFFSET -eq -1} |
Select-Object MENU, PARENT, MENU_GRP, MENU_IDX, MENU_OFFSET |
Format-Table
Returns
MENU PARENT MENU_GRP MENU_IDX MENU_OFFSET
---- ------ -------- -------- -----------
typeInstallation LICENSE 0 0 -1
activate 0 1 -1
NAME HOST 0 2 -1
IP 0 3 -1
routes 0 4 -1
users 0 5 -1
ANTI VIRUS SERVICEs 0 6 -1
NTP 0 7 -1
MEINBERG 0 8 -1
addPATH postgres 0 9 -1
check after CSI 0 10 -1
execute 0 11 -1
quite 0 12 -1
Example: If you want to filter all the rows where MENU_GRP = 6 AND MENU matches the word 'WINDOWS'
$csv | Where-Object {$_.MENU_GRP -eq 6 -and $_.MENU -match 'Windows'} |
Select-Object MENU, PARENT, MENU_GRP, MENU_IDX, MENU_OFFSET |
Format-Table
Returns:
MENU PARENT MENU_GRP MENU_IDX MENU_OFFSET
---- ------ -------- -------- -----------
WINDOWS DEFENDER ANTI VIRUS 6 13 12
I have a PowerShell command:
Get-AzWebAppAccessRestrictionConfig -ResourceGroupName RG1 -Name CoolTestWebApp1 | Select -ExpandProperty MainSiteAccessRestrictions
That once is ran outputs array:
RuleName : IP-1
Description :
Action : Allow
Priority : 1
IpAddress : 10.0.0.0/24
SubnetId :
RuleName : IP-2
Description :
Action : Allow
Priority : 2
IpAddress : 10.0.0.1/24
SubnetId :
How can I run a command for every entry in RuleName?
For example, something like:
Get-AzWebAppAccessRestrictionConfig -ResourceGroupName RG1 -Name CoolTestWebApp1 | Select -ExpandProperty MainSiteAccessRestrictions | ForEach-Object { Write-Host $RuleNameX }
That would execute:
Write-Host $RuleName1
Write-Host $RuleName2
Which in turn would output:
IP-1
IP-2
You pretty much had it:
Get-AzWebAppAccessRestrictionConfig -ResourceGroupName RG1 -Name CoolTestWebApp1 | Select -ExpandProperty MainSiteAccessRestrictions | ForEach-Object { Write-Host $_.RuleName }
Within a ForEach-Object, you can access the current objects attributes using $_.
i.e
ForEach-Object { $_.attributeName }
If the RuleName attribute contains an array of values, you could then iterate over them too:
$siteRestrictions = (Get-AzWebAppAccessRestrictionConfig -ResourceGroupName RG1 -Name CoolTestWebApp1).MainSiteAccessRestrictions
# Loop through objects
foreach($item in $siteRestrictions) {
# Loop through each RuleName
foreach($ruleName in $item.RuleName) {
# Do some logic here
}
}
Does PSCustomObject's know the order in which its properties are added?
# Order of properties
$o21 = New-Object PSCustomObject |
Add-Member NoteProperty a2 2 -passThru |
Add-Member NoteProperty a1 1 -passThru
$o21 | fl
a2 : 2
a1 : 1
$o12 = New-Object PSCustomObject |
Add-Member NoteProperty a1 1 -passThru |
Add-Member NoteProperty a2 2 -passThru
$o12 | fl
a1 : 1
a2 : 2
I want to read this order. How?
To get an ordered list of properties of an object in PowerShell, you can access the Properties collections through the hidden psobject memberset property:
PS C:\> $o12.psobject.Properties
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 1
TypeNameOfValue : System.Int32
Name : a1
IsInstance : True
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 2
TypeNameOfValue : System.Int32
Name : a2
IsInstance : True
Expand the Name property if you just want an ordered list of property names using Select-Object:
$PropertyNames = $o12.psobject.Properties |Select-Object -ExpandProperty Name
or using property enumeration (PowerShell 3.0+):
$PropertyNames = $o12.psobject.Properties.Name
To expand on Mathias' answer; if you are looking to get the property list for an array of objects, you'll need to do one of the following depending on how different the objects in the array are:
All objects in the array share the same properties:
This example will pull the first object of the array only and grab its property names
$PropertyNames = $o12[0].PSObject.Properties | Select-Object -ExpandProperty Name
Objects in the array do not share properties:
$PropertyNames = $o12 | ForEach-Object { $_.PSObject.Properties | Select-Object -ExpandProperty Name}
In both of the examples, the takeaway is that property enumeration will happen at the top level. If your top level is an object array and not a PSCustomObject/PSObject, then you'll return array properties and not the properties of the object/objects in the array:
PS> $obj.PSObject.Properties.Name
Count
Length
LongLength
Rank
SyncRoot
IsReadOnly
IsFixedSize
IsSynchronized
PS> $obj[0].PSObject.Properties.Name
Name
SamAccountName