Powershell script with multiple loops stopping after one - loops

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

Related

wildcard in array

How can I use the 1709 as a wildcard? The value 1709 is stored in an array as $MoveItem.Version, but I can't figure out how do a -like, when the value comes from an array, as I can't put in a wildcard *. I also tried to do a match.
The file name looks like this: REFW10-X86-1709_01-12-2017.wim.
The below code works fine, but I would like to automate it, so everything comes from the array. Is that possible?
Get-ChildItem -Path $OSPathTemp -Recurse | Where {
($_.Name -eq $MoveItem.File) -and
($_.Name -like "*1709*")
} | Select-Object -ExpandProperty FullName
$MoveItem.Version contains 1607,1706,1709. I would like to choose only the one with 1709. The final output should look like this:
foreach ($MoveItem in $MoveItems) {
Get-ChildItem -Path $OSPathTemp -Recurse | Where {
($_.Name -eq $MoveItem.File) -and
($_.Name -like $MoveItem.Version)
} | Select-Object -ExpandProperty FullName
}
The Array looks like this:
$MoveItem = #(
[pscustomobject]#{File="REFW10-X86-1709_01-12-2017.wim";Version=1709}
[pscustomobject]#{File="REFW10-X86-1706_01-12-2017.wim";Version=1706}
)
So you have a hash table (or similar) named $MoveItem that has a .File property that is a filename, and you have a .Versions property that's a string array?
Test name: REFW10-X86-1709_01-12-2017.wim
Get-ChildItem -Path $OSPathTemp -Recurse |
ForEach-Object {
If ($_.Name -match '-\d{4}_') { $Version = $Matches[0] }
If ($Version -in $MoveItem.Versions -and
$_.Name -eq $MoveItem.File) { $_.FullName }
}

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

How to save powershell script results to a file

I am using the script below to display all the subfolders' names and the count of files in those folders. I cannot figure out how to save the results to a file. I have tried everything I could and searched online for hours.
dir -recurse | ?{ $_.PSIsContainer } | %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count }
Do not use Write-Host. That cmdlet writes to the console only (i.e., you cannot redirect it to a file).
Use something like this instead:
Get-ChildItem -Recurse | Where-Object { $_.PSIsContainer } | ForEach-Object {
$_.FullName
}
Found another way of doing it that lets me save to a file:
ls -rec | ? {$_.mode -match 'd'} | select FullName, #{N='Count';E={(ls $_.FullName | measure).Count}} | Out-File C:\results.txt
I took your code and I upgraded it. try this:
$OUserOut = #()
Get-ChildItem -Recurse | Where-Object { $_.PSIsContainer } | ForEach-Object {
$ObjProperties = New-Object PSObject
Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name FullName -Value $_.FullName
Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name InternalObj -Value (dir $_.FullName | Measure-Object).Count
$OUserOut += $ObjProperties
}
$OUserOut | Out-GridView -Title "Objects"
$OUserOut | Export-Csv $env:USERPROFILE\Desktop\Out.csv
The two last lines have the information for the output file. The "Out-GridView" it's a table for show you the information, and the other line it's for export the result to a csv file.

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-File names in a directory with same letters

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

Resources