How can I use a variable as Application Pool name? - powershell

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 :
...
#>

Related

PowerShell find firewall rule by port

What I want to do
I want to list all firewall rules involving some ports and list their display name but the only way I found for now displays only the port part and has no idea what the display name is.
First the basics
If we call Show-NetFirewallRule without argument, it lists all rules and each is formatted like that (notice DisplayName that is on "root" and LocalPort that is under Get-NetFirewallPortFilter):
Name : {96022E5F-666B-4E9E-8BD4-040498CEF1F5}
DisplayName : Google Chrome (mDNS-In)
Description : Inbound rule for Google Chrome to allow mDNS traffic.
DisplayGroup : Google Chrome
Group : Google Chrome
Enabled : True
Profile : Any
Platform :
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : The rule was parsed successfully from the store. (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local
RemoteDynamicKeywordAddresses :
$_ | Get-NetFirewallAddressFilter
LocalAddress : Any
RemoteAddress : Any
$_ | Get-NetFirewallServiceFilter
Service : Any
$_ | Get-NetFirewallApplicationFilter
Program : C:\Program Files\Google\Chrome\Application\chrome.exe
Package :
$_ | Get-NetFirewallInterfaceFilter
InterfaceAlias : Any
$_ | Get-NetFirewallInterfaceTypeFilter
InterfaceType : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallSecurityFilter
Authentication : NotRequired
Encryption : NotRequired
OverrideBlockRules : False
LocalUser : Any
RemoteUser : Any
RemoteMachine : Any
What I tried
The closer, I think, is
Show-NetFirewallRule | where {$_.LocalPort -eq "5353" -or $_.LocalPort -eq "5354"}
But it returns only Get-NetFirewallPortFilter part as said above:
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
On same basis I tried:
Get-NetFirewallRule | where { $_.Get-NetFirewallPortFilter.LocalPort -Eq "5353" }
that displays a parse error, and all
Get-NetFirewallRule | where { $_.NetFirewallPortFilter.LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).$_.LocalPort -Eq "5353" }
That gives no result.
Based on https://itluke.online/2018/11/27/how-to-display-firewall-rule-ports-with-powershell/, I tried:
Get-NetFirewallRule |
Format-Table -Property Name,
DisplayName,
DisplayGroup,
#{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},
#{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}},
#{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},
#{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}} | where {$PSItem.LocalPort -eq "5353"}
But it seems doing nothing, and when I call it without the | where ... it is very slow, displaying approximatively 1 line per second. Note I tried also $_.LocalPort -eq "5353" and $_ -like "5353" in where.
I also tried
Get-NetFirewallRule | Get-NetFirewallPortFilter | Where-Object -Property { $_.LocalPort -Eq "5353" }
But is returns nothing (and is also very slow).
Workaround
For now I use a dirty "workaround", I call Show-NetFirewallRule > NetFirewallRule.txt and search manually in file, but I would like to have a script that does this automatically for me (and that is not very slow, since some commands that seems close to the answer are very slow).
The question
Anybody knows if/how can I achieve that ?
Thanks !
I believe you want to start with Get-NetFirewallPortFIlter, filter the results, and pass them to Get-NetFirewallRule. That should be much faster than looping on all results of Get-NetFirewallRule and testing each yourself.
Example (indented for readability, but can be a one-liner, of course):
Get-NetFirewallPortFilter |
Where-Object { $_.LocalPort -eq 5353 } |
Get-NetFirewallRule
Searched 717 rules and an equivalent 717 port filters in 1.2 seconds with 6 results.
If you'd like to show the port information alongside each rule, something like (this may or might not be optimal, but ...):
Get-NetFirewallPortFilter |
Where-Object { $_.LocalPort -eq 5353 } |
ForEach-Object {
"----"
"Rule"
"----"
$_ | Get-NetFirewallRule
"-----------"
"Port Filter"
"-----------"
$_
}
With the above, you'll still be looping over the filtered results rather than the entire set of rules.
This is what works for me:
Get-NetFirewallRule |Select-Object -First 20 -PipelineVariable Rule |
Get-NetFirewallPortFilter |Where-Object LocalPort -in 'RPCEPMap', 'Any' |
ForEach-Object { [pscustomobject]#{ name = $Rule.DisplayName; port = $_.LocalPort } }
But there are two tricky things here to deal with:
The common parameter -PipelineVariable is limited (see the information in the description along with the Note and the Caution) which I assume covers the reason why you can't remove the |Select-Object -First 20 part and place the -PipelineVariable Rule directly on the Get-NetFirewallRule cmdlet (but I don't fully understand the implication myself)
The Get-NetFirewallPortFilter cmdlet requires a CimInstance rather than e.g. a usual (PS)Object. This presumable explains why you can't replace the |Select-Object -First 20 with |Select-Object * know that former command actually places a reference to object output by Get-NetFirewallRule. See: Select-Object -First affects prior cmdlet in the pipeline
Update
as there appears to be a bug: "after some tests, it started to return always same name, of a "random" rule not involving port(s) I am searching for"
This is probably because the CimInstances run asynchronously and the refences in the -PipelineVariable are probably being overwritten (even with NetFirewallRule -ThrottleLimit 1 -OutBuffer 1). This means that this probably can't piped correctly.
Anyways, this (doing a filter on each specific rule instance) also appears to work for me:
Get-NetFirewallRule |ForEach-Object {
$Ports = $_ |Get-NetFirewallPortFilter |Where-Object LocalPort -in 'RPCEPMap', 'Any'
if ($Ports) { $_ |Select-Object DisplayName, #{n='LocalPort';e={$Ports.LocalPort} } }
}
Trying to parse something like "1000-2000" in localport. This fails with multiple false outcomes in the same rule.
$target = 8555
get-netfirewallportfilter |
? { $_.localport -match '-' } |
? { $_.localport | foreach { if ($_ -match '-') { $beg,$end = $_ -split '-';
[int]$beg -le $target -and [int]$end -ge $target }}} |
select instanceid,#{n='localport';e={"$($_.localport)"}}
instanceid localport
---------- ---------
NVS-FrameServer-In-TCP-NoScope 554 8554-8558
{E7D045E7-643F-4A91-94FF-63518836FA72} 5353 7200-17210 8889
{9823D038-1960-4767-9290-B36AA995FBB3} 5000 7000 7100 50000 7200-17210 8888
{123BF547-E50B-4A9D-A9E7-0FAE15D9C665} 7200-17210
IIS-WebServerRole-FTP-Passive-In-TCP 1024-65535
{25931D39-0705-4E63-A10C-E5F16BD17E0A} 7200-17210
{D6E50A26-B3A7-4683-A9FC-8485ED2B38BA} 5000 7000 7100 50000 7200-17210 8888
{B88115EB-F6B6-48D2-B194-723414C249B5} 5353 7200-17210 8889

Powershell. Run Command for Every Specific String in Array

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
}
}

Select-String showing a line that does not exist on the original output

I am trying to discover which IP and interface a Windows machine is using to communicate with another machine.
This is the command that I am executing:
Find-NetRoute -RemoteIpAddress 192.168.1.10 | Select-String -Pattern "IPAddress"
And this is the response:
MSFT_NetIPAddress (Name = ";C?8;#B8:8;::55?55;55;", CreationClassName = "", SystemCreationClassName = "", SystemName = "")
I do not understand this output because the output of Find-NetRoute without the Select-String is this:
IPAddress : 192.168.0.100
InterfaceIndex : 4
InterfaceAlias : Wi-Fi
AddressFamily : IPv4
Type : Unicast
PrefixLength : 24
PrefixOrigin : Dhcp
SuffixOrigin : Dhcp
AddressState : Preferred
ValidLifetime : 01:10:34
PreferredLifetime : 01:10:34
SkipAsSource : False
PolicyStore : ActiveStore
Caption :
Description :
ElementName :
InstanceID : :8:8:8:9:55>55;C<8;#B8:8<?>55;
AdminDistance :
DestinationAddress :
IsStatic :
RouteMetric : 0
TypeOfRoute : 3
AddressFamily : IPv4
CompartmentId : 1
DestinationPrefix : 0.0.0.0/0
InterfaceAlias : Wi-Fi
InterfaceIndex : 4
InterfaceMetric : 50
NextHop : 192.168.0.254
PreferredLifetime : 02:00:00
Protocol : NetMgmt
Publish : No
State : Alive
Store : ActiveStore
ValidLifetime : 02:00:00
PSComputerName :
ifIndex : 4
Is Select-String really supposed to work similar to "grep" on Windows Powershell?
Aside from | findstr /i, here's another probably not that convenient workaround. You could shorten -stream to -s.
Find-NetRoute -RemoteIpAddress 192.168.1.10 | Out-String -Stream | Select-String ipaddress
IPAddress : 192.168.0.100
You can search property names with select-object:
Find-NetRoute -RemoteIpAddress 192.168.1.10 | select *address*
I wish I could search the property values like this, but unfortunately it doesn't work:
Find-NetRoute -RemoteIpAddress 192.168.1.10 | where * -match 192
I suppose this works, but it outputs all the properties anyway. At least it only outputs matching objects.
Find-NetRoute -RemoteIpAddress 192.168.1.10 | where { $_ -match '192' }
[pscustomobject]#{name='joe';address='here'},
[pscustomobject]#{name='james';address='there'} | where { $_ -match 'th' }
name address
---- -------
james there
EDIT:
I came up with a "search-object" script that only returns the properties (and methods) that match, by name or value:
# search-object.ps1
param ($pattern)
begin {
$hash = #{}
}
process {
$obj = $_
$obj | Get-Member | foreach name |
foreach {
$name = $_
$value = $obj.$name
if ($name -match $pattern -or $value -match $pattern) {
$hash += #{$name = $value}
}
}
[pscustomobject]$hash
}
For example:
get-process cmd | search-object cmd
Modules : {System.Diagnostics.ProcessModule (cmd.exe), System.Diagnostics.ProcessModule
(ntdll.dll), System.Diagnostics.ProcessModule (KERNEL32.DLL),
System.Diagnostics.ProcessModule (KERNELBASE.dll),
System.Diagnostics.ProcessModule (msvcrt.dll)}
Path : C:\Windows\System32\cmd.exe
MainModule : System.Diagnostics.ProcessModule (cmd.exe)
ProcessName : cmd
Name : cmd
MainWindowTitle : cmd
Find-NetRoute -RemoteIpAddress 192.168.1.10 | search-object ipaddress
IPAddress
---------
192.168.0.100
When "Grepping" in PS I tend to lean on findstr.
Try this:
find-netroute -remoteipaddress 10.0.0.1 | findstr "IPAddress"
For me (thats my gateway IP) it returns:
IPAddress : 10.0.0.136
And just an FYI, yes, your syntax gave me the same data from InstanceID.
Here's what I think is happening. As #Lee_Dailey states, Select-String works with [String] instances. Find-NetRoute outputs [CimInstance] instances...
PS> Find-NetRoute -RemoteIpAddress 192.168.1.10 | ForEach-Object { $_.PSObject.TypeNames[0] }
Microsoft.Management.Infrastructure.CimInstance#ROOT/StandardCimv2/MSFT_NetIPAddress
Microsoft.Management.Infrastructure.CimInstance#ROOT/StandardCimv2/MSFT_NetRoute
...so some transformation to [String] needs to take place so the text can be searched. If you run this...
PS> Find-NetRoute -RemoteIpAddress 192.168.1.10 | ForEach-Object { [String] $_ }
MSFT_NetIPAddress (Name = ";C?8;#B8:8;::55?55;55;", CreationClassName = "", SystemCreationClassName = "", SystemName = "")
MSFT_NetRoute (InstanceID = ":8:8:8:9:55>55;C<8;#B8:8<?>55")
...you get the [String] representation of a MSFT_NetIPAddress and MSFT_NetRoute [CimInstance] instances. If you tack the original Select-String command onto that...
PS> Find-NetRoute -RemoteIpAddress 10.10.10.10 | ForEach-Object { [String] $_ } | Select-String -Pattern IPAddress
MSFT_NetIPAddress (Name = ";C?8;#B8:8;::55?55;55;", CreationClassName = "", SystemCreationClassName = "", SystemName = "")
...you get the original output, which is missing the MSFT_NetRoute line. The CIM class name MSFT_NetIPAddress is matched by the pattern IPAddress, which is why that line is present in the output.
My first thought was that it is not casting input objects to [String] but calling ToString() on them, and that is what the documentation suggests...
Inputs
System.Management.Automation.PSObject
You can pipe any object that has a ToString method to Select-String.
...but if I do that I get different text for the MSFT_NetIPAddress instance...
PS> Find-NetRoute -RemoteIpAddress 192.168.1.10 | ForEach-Object { $_.ToString() }
192.168.0.100
MSFT_NetRoute (InstanceID = ":8:8:8:9:55>55;C<8;#B8:8<?>55")
If you look through that documentation there are some mentions of its similarity to or getting it to work like grep and findstr. The issue here, though, is the input text it was searching was not what you thought it would be; the text you saw in your console from a bare Find-NetRoute command was not the same text that would get passed to Select-String via the pipeline.
By the way, if your intention was to just filter the output down to that first IPAddress property that is displayed by Find-NetRoute -RemoteIpAddress 192.168.1.10 then instead of searching the full text for IPAddress you could just "search" for matching property (sub)names with Select-Object...
PS> Find-NetRoute -RemoteIpAddress 192.168.1.10 | Select-Object -Property '*IPAddress*'
IPAddress
---------
192.168.0.100

Search and delete registry values containing string using Powershell

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?

Powershell, get ip4v address of VM

I'm new to powershell and I"m trying to get just the IPv4 address of a vm and save it as a string.
I can get all network attributes like so:
PS C:\Windows\system32> get-vm | select -ExpandProperty networkadapters | select vmname, macaddress, switchname, ipaddres
sses
VMName MacAddress SwitchName IPAddresses
------ ---------- ---------- -----------
foobar vSwitch {192.0.2.1, fe80::84a...
I can get both the v4 and the v6 ip address
PS C:\Windows\system32> $IP = ( GEt-VM -ComputerName $HVCOMPUTERNAME -VMName $HVNAME | Get-VMNetworkAdapter).IpAddresses
PS C:\Windows\system32> $IP
192.0.2.1
fe80::d47e:
----------
How can I get just the v4 address as a string?
Update
It looks like there is no object property that just includes the v4 address
PS C:\Windows\system32> GEt-VM -ComputerName $HVCOMPUTERNAME -VMName $HVNAME | Get-VMNetworkAdapter | Format-List -Property *
IovWeight : 0
IovQueuePairsRequested : 1
IovQueuePairsAssigned : 0
IovInterruptModeration : Default
IovUsage : 0
ClusterMonitored : True
VirtualFunction :
IsLegacy : False
IsManagementOs : False
IsExternalAdapter : False
Id : Microsoft:xxxxxxxxxxx
AdapterId : xxxxxxxxxxx
DynamicMacAddressEnabled : True
MacAddress : 00155D5B9B14
MacAddressSpoofing : Off
SwitchId : xxxxxxxxxxx
Connected : True
PoolName :
SwitchName : vSwitch
AclList : {}
ExtendedAclList : {}
IsolationSetting : Microsoft.HyperV.PowerShell.VMNetworkAdapterIsolationSetting
CurrentIsolationMode : Vlan
RoutingDomainList : {}
DhcpGuard : Off
RouterGuard : Off
PortMirroringMode : None
IeeePriorityTag : Off
VirtualSubnetId : 0
DynamicIPAddressLimit : 0
StormLimit : 0
AllowTeaming : Off
VMQWeight : 100
IPsecOffloadMaxSA : 512
VmqUsage : 0
IPsecOffloadSAUsage : 0
VFDataPathActive : False
VMQueue :
MandatoryFeatureId : {}
MandatoryFeatureName : {}
VlanSetting : Microsoft.HyperV.PowerShell.VMNetworkAdapterVlanSetting
BandwidthSetting :
BandwidthPercentage : 0
TestReplicaPoolName :
TestReplicaSwitchName :
StatusDescription : {OK}
Status : {Ok}
IPAddresses : {192.0.2.1, fe80::xxxxxxxxxxx}
ComputerName : xxxxxxxxxxx
Name : Network Adapter
IsDeleted : False
VMId : xxxxxxxxxxx
VMName : foobar
VMSnapshotId : 00000000-0000-0000-0000-000000000000
VMSnapshotName :
Key :
You can just filter out any IP that has ":" in it, as such:
$IP | ?{$_ -notmatch ':'}
Assuming there is only 1 V4 address, and that the v4 address is the first output, do:
$IP = ( GEt-VM -ComputerName $HVCOMPUTERNAME -VMName $HVNAME | Get-VMNetworkAdapter).IpAddresses | Select-String -List 1
IPAddresses looks like an array or list and you only want the first one so try:
$IP = ( GEt-VM -ComputerName $HVCOMPUTERNAME -VMName $HVNAME | Get-VMNetworkAdapter).IpAddresses[0]