Powershell-File names in a directory with same letters - file

I need to write a powershell script, which list file names that contains the same letters, only difference is the sort of the letters.
My first oppinion is to sort the letters in alphabet, and if it fit, then they match, but i need some help for do that
Get-ChildItem $path | foreach {$i=1}`
{
$asd=$_ | sort-object
Get-ChildItem $path | foreach {$i=1}`
{
$wasd=$_ | sort-object
if($asd -eq $wasd)
{
Write-Host $_
}
}
}
This files match for my criteria:
asd.txt, dsa.txt, because contains same letters

I think this is doing what you want.
function get-Stringcharacters {
param($string)
[char[]]$string | sort-object
}
dir $path | group-object #{E={get-Stringcharacters $_.Name}} |
where-object {$_.Count -gt 1} |
select-object -ExpandProperty Group |
foreach { write-host $_.Name }

gci | % { ($.BaseName.ToString().toCharArray() | Sort) -join ''} | Group | ? { $.Count -gt 1 } | Select Name

Related

Function return array in PowerShell

I have a problem when I'm trying to return an array from a PowerShell function.
My function:
function filter-SWCluster {
param($Path, $FolderList)
$OldSWCluster = New-Object System.Collections.ArrayList
ForEach ($y in $FolderList) {
Get-ChildItem -Path $Path -Filter $y* | sort { [version]($_.Name -replace '^.*_(\d+(\.\d+){1,3})$', '$1') } -Descending | Select-Object -skip 3 | ForEach-Object { $OldSWCluster.Add($Path + "\" + $_) }
}
Write-Output $OldSWCluster
}
The function call:
$FilerSWCluster = filter-SWCluster $NetworkPath $SWCluster
The output I get:
0 1 \\server.domain\C$\TEMP\Folders\Testcluster_1.0.2 \\server.domain\C$\TEMP\Folders\Testcluster_1.0.1
The output I want and need would be:
\\server.domain\C$\TEMP\Folders\Testcluster_1.0.2 \\server.domain\C$\TEMP\Folders\Testcluster_1.0.1
I need just the paths. I know there will already be some solutions, but please excuse me. I didn't find one which was working for me or I were to dumb to use it right (could be).
You could also wrap the Add method with the [void] class accelerator. It will hide any output, like this:
function filter-SWCluster {
param($Path, $FolderList)
$OldSWCluster = New-Object System.Collections.ArrayList
ForEach ($y in $FolderList) {
Get-ChildItem -Path $Path -Filter $y* | sort { [version]($_.Name -replace '^.*_(\d+(\.\d+){1,3})$', '$1') } -Descending | Select-Object -skip 3 | ForEach-Object { [void]$OldSWCluster.Add($Path + "\" + $_) }
}
Write-Output $OldSWCluster
}
wOxxOm already provided you a solution to your problem. However, consider to just return the path using a simple select. You also don't have to join the path since the FullName property already contains the full path:
function filter-SWCluster {
param($Path, $FolderList)
ForEach ($y in $FolderList) {
Get-ChildItem -Path $Path -Filter $y* |
sort { [version]($_.Name -replace '^.*_(\d+(\.\d+){1,3})$', '$1') } -Descending |
Select-Object -skip 3 |
select -ExpandProperty FullName
}
}

PowerShell finding duplicates in CSV and outputting different header

I guess the question is in the title.
I have a CSV that looks something like
user,path,original_path
I'm trying to find duplicates on the original path, then output both the user and original_path line.
This is what I have so far.
$2 = Import-Csv 'Total 20_01_16.csv' | Group-Object -Property Original_path |
Where-Object { $_.count -ge 2 } | fl Group | out-string -width 500
This gives me the duplicates in Original_Path. I can see all the required information but I'll be danged if I know how to get to it or format it into something useful.
I did a bit of Googleing and found this script:
$ROWS = Import-CSV -Path 'Total 20_01_16.csv'
$NAMES = #{}
$OUTPUT = foreach ( $ROW in $ROWS ) {
IF ( $NAMES.ContainsKey( $ROW.Original_path ) -and $NAMES[$ROW.original_path] -lt 2 )
{ $ROW }
$NAMES[$ROW.original_path] += 1 }
Write-Output $OUTPUT
I'm reluctant to use this because, well first I have no idea what it's doing. So little of the makes any sense to me, I don't like using scripts I can't get my head around.
Also, and this is the more important part, it's only giving me a single duplicate, it's not giving me both sets. I'm after both offending lines, so I can find both users with the same file.
If anyone could be so kind as to lend a hand I'd appreciate it.
Thanks
It depends on the output format you need, but to build on what you already have we can use this to show the records in the console:
Import-Csv 'Total 20_01_16.csv' |
Group-Object -Property Original_path |
Where-Object { $_.count -ge 2 } |
Foreach-Object { $_.Group } |
Format-Table User, Path, Original_path -AutoSize
Alternatively, use this to save them in a new csv-file:
Import-Csv 'Total 20_01_16.csv' |
Group-Object -Property Original_path |
Where-Object { $_.count -ge 2 } |
Foreach-Object { $_.Group } |
Select User, Path, Original_path |
Export-csv -Path output.csv -NoTypeInformation

powershell pipe to array returns as character array

I am trying to build an array with the results of the following powershell script. I would then like to only output the unique results in that array (I am expecting duplicates). I tried but it does not work. One thing I noticed is that my array is being converted to a character array. So if I call a single object in the array ($array[1]) it only displays one character, which may be why the select -unique is not working.
Please help.
$servers="Server1","server2"
$regex="(\.\d\d\d.*\()"
$path = "SomePath"
$yesterday = (get-date).Date.AddDays(-1)
Foreach ($server in $servers) {Get-ChildItem -Path $path -recurse | where { $_.LastWriteTime -le $yesterday } | ForEach-Object { Get-Content -Path "$_" -TotalCount 2 | select-string $regex | % { $_.Matches } | % { $array += $_.Value.Substring(5,6) } }}
$array|select -Unique
If you initialize the $array value as an array, then your code will work. Without this knowledge, PowerShell is treating $array += like concatenating strings together.
$array = #()
$servers="Server1","server2"
$regex="(\.\d\d\d.*\()"
$path = "SomePath"
$yesterday = (get-date).Date.AddDays(-1)
Foreach ($server in $servers) {Get-ChildItem -Path $path -recurse | where { $_.LastWriteTime -le $yesterday } | ForEach-Object { Get-Content -Path "$_" -TotalCount 2 | select-string $regex | % { $_.Matches } | % { $array += $_.Value.Substring(5,6) } }}
$array|select -Unique

Iterating through multiple email bodies and pass to hash array

I am trying to iterate through emails, that have a specific subject line, and have the body of matching emails parsed and passed to a hash array. There is an issue with how I am trying to deal with multiple email bodies that is causing an issue.
$ol=New-Object -ComObject Outlook.Application
$ns=$ol.GetNameSpace('MAPI')
$inbox=$ns.GetDefaultFolder(6)
$Goodsubject='Interesting Email'
$mail = $InBox.items |
Where-Object{
$_.Unread -and $_.Subject -match $Goodsubject
#$_.Subject -match $Goodsubject
} |
Sort-Object ReceivedTime -Descending |
Select-Object Subject,ReceivedTime,Body,SenderName
# Select-Object Body
$mail | %{
$_.Body | %{$interestinghash = #{}} {
if ($_ -match "(.*): (.*)") {
$interestinghash[$matches[1]]=$matches[2];
}
}
Assuming the email has 4 line, each with a key: value, and I look at $interestinghash, I will only have the a key value pair for a email. I will not have all 4. That said, I can replace the following line:
$mail | %{
$_.Body | %{$interestinghash = #{}} {
if ($_ -match "(.*): (.*)") {
$interestinghash[$matches[1]]=$matches[2];
}
}
With:
$mail | %{$interestinghash = #{}} {
if ($_ -match "(.*): (.*)") {
$interestinghash[$matches[1]]=$matches[2];
}
}
If I do this it will give me all 4 values but will only look at 1 email. I am not sure what I am doing wrong here.

Powershell script with multiple loops stopping after one

I am working on a script to set file permissions using the ShareUtils module and for some reason it is not continuing to my second and third stage loops. Not sure why?
$input | Where-Object {$_.AccessMask -like 2032127} | Foreach-Object {
Get-Share -Name $_.Name | Add-SharePermission $_.User Allow FullControl | Set-Share
}
$input | Where-Object {$_.AccessMask -like 1245631} | Foreach-Object {
Get-Share -Name $_.Name | Add-SharePermission $_.User Allow Change | Set-Share
}
$input | Where-Object {$_.AccessMask -like 1179817} | Foreach-Object {
Get-Share -Name $_.Name | Add-SharePermission $_.User Allow Read | Set-Share
}
Try to reset $input. Once $input is called it processes all of its elements and moves forward until it gets to the last item.
$input.reset()
UPDATE
You could also rewrite the solution, an example would be:
$input | Foreach-Object {
$perm = switch($_.AccessMask)
{
2032127 {'FullControl'; break}
1245631 {'Change'; break}
1179817 {'Read'; break}
}
if($perm)
{
Get-Share -Name $_.Name | Add-SharePermission $_.User Allow $perm | Set-Share
}
}

Resources