So I have this PowerShell one-liner that gives me back my groups:
$groups = Get-ADPrincipalGroupMembership userName | ForEach-Object {Write-Host $_.Name -BackgroundColor Red} |Out-String; $groupsWithSpaces = foreach ($groups in $groupsWithSpaces) {Select-String -AllMatches '[\\s+,]' | Write-Host}; Write-Host $groupsWithSpaces
How am I using the regex wrong? I am trying to return only groups that have a whitespace on the end. I am always returning every group, and I only want the ones that have white space on the end. I can get true/false, but...help please.
Thanks!
In your regex you were escaping one of the slashes. Making it so you were looking for groups with a literal slash followed by at least on letter s.
If you are just trying to find the group with spaces in them this would work
Get-ADPrincipalGroupMembership username |
Where-Object{$_.Name -match "\s"} |
select -ExpandProperty Name |
Write-Host -BackgroundColor red
I formatted it for easy reading
If you wanted to see the whole list with the empty ones standing out you could also use and if statement
Get-ADPrincipalGroupMembership username | select -ExpandProperty Name | ForEach-Object{
If( $_ -match "\s"){
Write-Host $_ -BackgroundColor red
} Else {
Write-Host $_
}
}
I think this is the false variable --> $groupsWithSpaces = foreach ($groups in -->HERE<--$groupsWithSpaces-->HERE<--) {Select-String -AllMatches '[\\s+,]' | Write-Host}; Write-Host $groupsWithSpaces.
Work this one?
$groups = Get-ADPrincipalGroupMembership userName | ForEach-Object {Write-Host $_.Name -BackgroundColor Red} |Out-String; $groupsWithSpaces = foreach ($group in $groups) {If ($group[-1] -eq " ") {Write-Host $group}}; Write-Host $groupsWithSpaces
Related
For example, you specified a variable as shown below.
$data1 = get-psdrive | where-object {$_.name -like 'c'} | select -expandproperty used
$data2 = get-psdrive | where-object {$_.name -like 'c'} | select -expandproperty free
echo $data1,data2
The output is vertical.
$data1
$data2
I used write-host -nonewline to display output horizontally, but the command does not export to txt
write-host $data1 -nonewline; write-host $data2 -nonewline >> c:\test.txt
How can I display horizontally and export in txt?
How about converting to json (or csv)? Note that ">>" can mix encodings, but add-content doesn't.
get-psdrive c | select used, free | ConvertTo-Json -Compress |
add-content test.txt
get-content test.txt
{"Used":217365741568,"Free":21004943360}
Or just join them. Too bad select -expand doesn't work with multiple properties.
psdrive c | % { ($_.used,$_.free) -join ',' }
217382371328,20988313600
You can't use Write-Host for this. Even if you change to Write-Host -NoNewLine it'll still never work because Write-Host is intended for directly writing into the screen and can't be redirected unless you use PowerShell 5+ and redirect the stream number 6 (Information stream)
Write-Host -NoNewLine $data1,$data2 6>output.txt
in which case it doesn't print out to string of course. In short Write-Host in PowerShell 5+ doesn't write to stdout but the Information stream
The real solution to writing to screen with the ability to redirect to file or pipe to another command is to use Write-Output (which echo is an alias to), and simply use a single string to write to a single line
Write-Output "$data1,$data2"
echo "$data1,$data2"
echo ($data1 + "," + $data2)
See Write-Host Considered Harmful for more details
Use a double quote string with your variables: Write-Host “$data1,$data2”
Read more https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-7.1
I'm trying to get all smb shares on my windows server with all user permissions on them for inventory check.
This is what i have:
$Shares = Get-SmbShare
foreach($Share in $Shares)
{
Get-SmbShareAccess -Name $Share.Name | Where-Object {$_.AccountName -Match "DOMAINNAME"}
}
Which gets me all domain users with their shares and which access they have.
But it only shows name of folder. I would like its gonna show full path on the server (Not UNC)
And it would be exportable in csv format.
When i do:
$Shares = Get-SmbShare
foreach($Share in $Shares)
{
Get-SmbShareAccess -Name $Share.Name | Where-Object {$_.AccountName -Match "PRAGUELOFTS"} | Export-Csv -Path C:\perms.csv
}
It only exports the last user.
You can define your output columns very precisely when you pass to Select-Object an array of hashes in this format: #{name="xyz"; expr={ calculated value }}.
This way you can unify values from multiple sources, such as "share" and "share access", and manually calculated values, into one custom result.
Get-SmbShare | Where-Object Special -eq $false | ForEach-Object {
$share = $_
$share | Get-SmbShareAccess | Where-Object AccountName -Match "DOMAINNAME" | Select-Object #(
#{name="UncPath"; expr={ "\\" + $env:COMPUTERNAME + "\" + $share.Name }}
#{name="LocalPath"; expr={ $share.Path }}
#{name="Account"; expr={ $_.AccountName }}
#{name="Type"; expr={ $_.AccessControlType }}
#{name="Right"; expr={ $_.AccessRight }}
)
}
You can then go on and pipe this into Export-Csv -Path C:\perms.csv.
As for your second question - this
foreach ($Share in $Shares)
{
Get-SmbShareAccess -Name $Share.Name | Export-Csv -Path C:\perms.csv
}
only gives you the last result in the CSV file because it literally says "for each share, write a CSV file". You keep overwriting the same file in every loop iteration.
Collect all the results into a variable first
$results = foreach ($Share in $Shares) {
# ...
}
and then create the output file
$results | Export-Csv -Path C:\perms.csv
I want to get a list of all ad computers excluding the servers that are in a text file. Here's my code:-
$excludedServers = (Get-Content
"C:\Users\testuser\Documents\RdpDisconnectedSessions\ExcludedServers.txt").name #| Sort-Object
Get-ADComputer -Filter * | Where { $_.DistinguishedName -like "*Computers*" -and $_.DistinguishedName -notmatch $excludedServers } | Select-Object Name
Any advise please ?
First, Get-Content is not going to bring back objects so the .name portion is not going to work. If it's just a list of computernames, then simply change it to.
$excludedServers = Get-Content "C:\Users\testuser\Documents\RdpDisconnectedSessions\ExcludedServers.txt"
If it's a CSV with a name column, then you can do it a few ways. Sticking with the format you had this would work
$excludedServers = (Import-Csv "C:\Users\testuser\Documents\RdpDisconnectedSessions\ExcludedServers.txt").name
Now that you have your list of names, you can filter like this (assuming it is actually the names of the servers and not their distinguished name)
Get-ADComputer -Filter * | Where { $_.DistinguishedName -like "*Computers*" -and $_.name -notin $excludedServers } | Select-Object Name
I have a problem with my Script.
I wanted to make a Script which makes a list of software which is found in a specific registry path
and see if this software equals installed software. and if so it should output me the uninstall string.
but right now it does not work as wanted. it never show me the output I wanted even if its similar. As Example i have the Program Git as Branding and in the software I got Git version 2.26.2 but it wont output the uninstall string when I selected git.
My code is:
$branding = Get-ChildItem "HKLM:\Software\DLR\Branding" | Get-ItemProperty | Select-Object -expandProperty ProgramName
$software = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Select-Object -ExpandProperty DisplayName
ForEach ($brandinglist in $branding) {
$objCombobox.Items.Add("$brandinglist")
}
$objComboBox_SelectedIndexChanged=
{
$selectme = $objCombobox.SelectedItem
Write-Host $selectme
if ("$selectme" -like "*$software*") {
$uninstall = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object {$_.DisplayName -match "$electme" } | Select-Object -Property UninstallString
Write-Host "$uninstall"
}
}
You are trying the -like comparison wrong, in which you compare the selected item to an array of displaynames which doesn't work that way.
Also, there is no reason to get the Uninstall strings and Displaynames using an almost identical code twice.
Try
# get a string array of program names
$branding = Get-ChildItem -Path 'HKLM:\Software\DLR\Branding' | Get-ItemProperty | Select-Object -ExpandProperty ProgramName
$regPaths = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
# get an object array of DisplayName and UninstallStrings
$software = Get-ChildItem -Path $regPaths | Get-ItemProperty | Select-Object DisplayName, UninstallString
# fill the combobox with the (string array) $branding
$objCombobox.Items.AddRange($branding)
$objComboBox.Add_SelectedIndexChanged ({
$selectme = $objCombobox.SelectedItem
Write-Host $selectme
# get the objects that have a displayname like the selected item and write out the matching Uninstall strings
$software | Where-Object {$_.DisplayName -like "*$selectme*" } | ForEach-Object {
Write-Host $_.UninstallString
}
})
I'm having an issue sorting a hash table. I've broken down my code to just bare necessities so as not to overwhelm anyone with my original script.
Write-Host "PowerShell Version = " ([string]$psversiontable.psversion)
$h = #{}
$Value = #{SortOrder=1;v1=1;}
$h.Add(1, $Value)
$Value = #{SortOrder=2;v1=1;}
$h.Add(2, $Value)
$Value = #{SortOrder=3;v1=1;}
$h.Add(3, $Value)
$Value = #{SortOrder=4;v1=1;}
$h.Add(4, $Value)
Write-Host "Ascending"
foreach($f in $h.GetEnumerator() | Sort-Object Value.SortOrder)
{
Write-Host $f.Value.SortOrder
}
Write-Host "Descending"
foreach($f in $h.GetEnumerator() | Sort-Object Value.SortOrder -descending)
{
Write-Host $f.Value.SortOrder
}
The output is
PowerShell Version = 3.0
Ascending
2
1
4
3
Descending
2
1
4
3
I'm sure this is just a simple case of not knowing the correct usage of Sort-Object. The sort works correctly on Sort-Object Name so maybe it has something to do with not knowing how to handle the Value.SortOrder?
Sort-Object accepts a property name or a script block used to sort. Since you're trying to sort on a property of a property, you'll need to use a script block:
Write-Host "Ascending"
$h.GetEnumerator() |
Sort-Object { $_.Value.SortOrder } |
ForEach-Object { Write-Host $_.Value.SortOrder }
Write-Host "Descending"
$h.GetEnumerator() |
Sort-Object { $_.Value.SortOrder } -Descending |
ForEach-Object { Write-Host $_.Value.SortOrder }
You can filter using the Where-Object cmdlet:
Write-Host "Ascending"
$h.GetEnumerator() |
Where-Object { $_.Name -ge 2 } |
Sort-Object { $_.Value.SortOrder } |
ForEach-Object { Write-Host $_.Value.SortOrder }
You usually want to put Where-Object before any Sort-Object cmdlets, since it makes sorting faster.
I was using a hash table as a frequency table, to count the occurrence of words in filenames.
$words = #{}
get-childitem *.pdf | foreach-object -process {
$name = $_.name.substring($_.name.indexof("-") + 1, $_.name.indexof(".") - $_.name.indexof("-") - 1)
$name = $name.replace("_", " ")
$word = $name.split(" ")[0]
if ( $words.contains($word) ){
$words[$word] = $words[$word] + 1
}else{
$words.add($word, 1)
}
}
$words.getenumerator() | sort-object -property value
It's that last line that does the magic, sorting the hash table on the value(frequency).