How would I use an array with the contains operator - arrays

I have a CSV file and in that file are 2 columns (this is just for testing purposes before using actual files), I need to get all the data for the specific pets so Dog and Cat in this example.
I have put the animals I want the data for in an array but for some reason the statement is not working it just returns an empty file, when I use a string (so just "dog") in the place of the array then I get the data back fine. Is there anything i'm doing wrong
$Pets = "Dog", "Cat"
import-csv -Path "C:\Users\User\deletingRows.csv" | where Animal -Contains $Pets | export-csv -Path "C:\Users\User\Result.csv" -NoTypeInformation

I believe you're misunderstanding what -Contains is supposed to do. Since you're trying to match a field against more than one value (within $Pets), you're better of using the -In switch. See the working example below.
$Pets = "Dog", "Cat"
Import-Csv -Path "C:\Users\User\deletingRows.csv" | where "Animal" -In $Pets | Export-Csv -Path "C:\Users\User\Result.csv" -NoTypeInformation

Related

Trying to output a custom powershell object where I can align each line of two different variables containing Category:Description

I'm trying to do an network access control audit by grabbing a user's AD groups, their descriptions and then output them in a way shown by this example:
[User]
#[1]Groups : #[1]GroupDescription
#[2]...
#[3]...
Below is what I have at the moment.
$UserGroups = #{
User = Read-Host -Prompt "What user do You want to look up Access for?"
Groups = (Get-ADUser $User -Properties MemberOf).MemberOf
GroupsDescriptions = (Get-ADUser $User -Properties MemberOf).MemberOf | % {(Get-ADGroup $_ -Properties *).description}
}
$Object = New-Object psobject -Property $UserGroups
$Object | format-table | Export-Csv c:\tmp\test.csv
Though the output is very strange. I don't understand it. Below is a result of Get-Content C:tmp\test.csv
#TYPE Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
"ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo","shapeInfo","groupingEntry"
"033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format.TableHeaderInfo",
"9e210fe47d09416682b841769c78b8a3",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
"4ec4f0187cb04f4cb6973460dfe252df",,,,,
"cf522b78d86c486691226b40aa69e95c",,,,,
I have tried outputting to a .txt file using Out-file, but I always get each property cut off with a ... at the end. I've used the -Autosize and -Expand when formatting the data before piping it to the export line.
Any Suggestions or advice would be extremely helpful.
Things I'll be Looking at later
Go through each line in PowerShell object and extract variables
Powershell & ActiveDirectory - trying to output users in a group and their membership
Out-file crops my text when trying to output a table
Thanks!
As stated, only ever use Format-* cmdlets to produce for-display output, never for outputting data that must be processed programmatically later. What Format-Table outputs are objects representing formatting instructions, and it is their properties that ended up in your CSV file - see this answer for more information.
In order to include collections (arrays) in CSV output, you must convert them to a single string, using a self-chosen separator. Otherwise, Export-Csv simply calls .ToString() on the collection object itself, which yields the collection's type name, and no information about its elements.
Therefore, use something like the following, which uses ', ' as the separator string to represent the group names and descriptions in a single column each:
$UserGroups = [pscustomobject] #{
User = ($user = Read-Host -Prompt "What user do You want to look up Access for?")
Groups = ($groups = (Get-ADUser $User -Properties MemberOf).MemberOf) -join ', '
GroupsDescriptions = (
$groups | ForEach-Object { (Get-ADGroup $_ -Properties *).Description }
) -join ', '
}
$UserGroups | Export-Csv c:\tmp\test.csv
Note:
[pscustomobject] #{ ... } is used to directly construct a custom object, which is syntactic sugar available since PowerShell v3 that is simpler and more efficient than a New-Object call.
In order to use the result from your Read-Host call in later properties of your object definition, you must cache it in aux. variable $user (note that enclosing the assignment in (...) passes its value through.
Similarly, the result of the Get-ADUser call is cached in aux. variable $groups, so that it doesn't have to be repeated in the GroupsDescriptions value.
However, as zett42 points out, it may be cleaner to make the $user = ... and $groups = ... assignments separate statements and place them before the object construction.
The problem is that you pipe to Format-Table before you pipe to Export-Csv. Only use Format-Table for displaying things on screen. The fix is to just remove that.
$Object | Export-Csv c:\tmp\test.csv
Thanks to this post Here and mklement0. I was able to figure out the formatting portion of this problem.
Now I have the remaining code that exports it exactly as intended.
$user= Read-Host -Prompt "What user bonehead?"
$object = Get-ADPrincipalGroupMembership $user
$Table = $object | ForEach-Object {
[pscustomobject] #{
Groups = $_.Name
GroupDesc = (Get-ADGroup $_ -Properties *).Description
GroupOwner = (Get-ADGroup $_ -Properties *).Info
}
}
$Table | Export-csv -NoTypeInformation c:\tmp\test.csv
The -NoTypeInformation helps eliminate the header on the .csv files and the piped Group info through the ForEach-Object cmdlet helped insure every object had it's own row in excel.

Powershell Comparing 2 Object arrays based on Properties of the Objects inside without losing the Format

I have a problem where i need to compare 2 PSObject arrays based on a property of the objects inside and i cant lose the format of the data in $neudaten.
Im trying to achieve this for now 5 hours and i can smell the victory by it wont let me touch it xD
Would be nice if u could help
$neudaten = Get-Content -Path $neudatenpf | Select-Object -skip 1 |`
ConvertFrom-Csv `
-Delimiter ";"`
-Header $categoriesCSV
$neudaten = $neudaten | Where-Object -Property ID -NE $useralt.ID

Recursively delete folders where folder name contains a number

Good afternoon all,
I am attempting to delete folders at a specific location containing a number in the name, which can be any number in the array.
$fso = New-Object -com "Scripting.FileSystemObject"
$Versionarray = (13..20)
$folder =
$fso.GetFolder("$env:USERPROFILE\appdata\local\Microsoft\OneDrive")
foreach ($subfolder in $folder.SubFolders)
{
If ($subfolder.Name -match "$Versionarray")
{
remove-item $subfolder.Path -Verbose
}
}
Please see an example of the following folders it will sift through below:
18.172.0826.0010
18.172.0826.0010_2
18.172.0826.0015
18.172.0920.0015
18.172.0920.0015_1
logs
settings
setup
If I change the "VersionArray"array to the variable "18" instead, it will start to remove the folders. It doesn't appear to be going through each number of the array. I need it to be an array to future-proof the script as the number represents a version of OneDrive.
Thank you for looking over this.
Going from your initial idea to have a list of items that must be contained in the subfolder name, we can do a pipeline like this:
$Versionarray = 13..20
Get-ChildItem "$env:LOCALAPPDATA\Microsoft\OneDrive" -Recurse | Where-Object {
$item = $_
$item -is [System.IO.DirectoryInfo] -and (
$Versionarray | Where-Object { $item.Name.Contains($_) }
)
} | Remove-Item -WhatIf
Notes:
Get-ChildItem returns all subfolders and files in a folder. Drop -Recurse if you don't need that.
Where-Object filters any list of objects according to a condition. Any result other than 0, $false, $null, or the empty string/empty list will be considered $true. It's not necessary to actually return $true, as long as anything is returned at all.
$_ is the "current item" in the pipeline
$foo -is [Fully.Qualified.ClassName] checks if an object is of a certain class. In this case, we only want to look at System.IO.DirectoryInfo objects and ignore all files.
$Versionarray | Where-Object { $item.Name.Contains($_) } filters the $Versionarray down to those elements that are contained in the folder name. You could use .StartsWith() or any other method of .NET strings in its place.
Any object that "survives" the Where-Object filter is passed to Remove-Item
-WhatIf performs a dry-run, drop it when you're sure the right thing will happen.

Extract partial line of text from text file

I need to keep the first 5 characters from data being pulled from a text file.
Data looks like this:
S1831KWT0081
S2004KWT0083
S2351KWT0085
S0054KWT0087
Results should looks like this:
S1831
S2004
S2351
S0054
I can get it working when setting the variable within PowerShell:
PS> $a = "S1831KWT0081"
PS> $a.Substring(0, $a.IndexOf('K'))
S1831
but I'm stuck when trying to pull from a text file.
To solve this, you will need to parse the text file on a line-by-line basis. Basically treating each line as a value in an array.
Get-Content location.txt | foreach { $_.Substring(0, $_.IndexOf('K')) }
Another option would be a regular expression replacement:
(Get-Content 'C:\path\to\input.txt') -replace '^(.{5}).*', '$1'
That would also allow you more specific matches, e.g. like this:
$re = '^([a-z]\d{4}).*'
(Get-Content 'C:\path\to\input.txt') -match $re -replace $re, '$1'
Just to show there always is more than one PoSh way ;-)
gc .\input.txt|%{$_.split('K')[0]}
Or the more verbose version
Get-Content .\input.txt |
ForEach-Object { $_.split('K')[0] }

Invoke-WebRequest : Cannot bind parameter 'Uri'. Cannot convert the "#{

Would like to retrive innerText of a P html element for all the URLS i got listed in a text file. I'm rather newbie for this, but thought i can solve it. Atm. i've failed, as i can't handle how i shall pass each array items for the loop correctly:
$theURLS = Import-CSV linkek_alatt.txt
$item = New-Object System.Collections.ArrayList
for ($i=0; $i -le $theURLS.length;$i++)
{
foreach($item in $theURLS)
{
$Site = Invoke-WebRequest -URI $item
$Igotit = $Site.AllElements | Where-Object {$_.tagName -eq "P"} |
Select -First 1 -Skip 3 -ExpandProperty innerText
$Igotit
}
}
> FilteredContent.txt
The Filtered file shall contain the informations.
For now, i receive a "Invoke-WebRequest : Cannot bind parameter 'Uri'. Cannot convert the "#{" error and i see repeated first URL and a random - the one for next step - one in the error message. Any ideas welcome.
Best regards,
Geza
Per the comments, the issue occurs because you are using Import-CSV here:
$theURLS = Import-CSV linkek_alatt.txt
This attempts to create a PowerShell object by using the first line of text in the file as headers.
If your .txt file is not a .csv file and you want to return an array of strings, instead use Get-Content:
$theURLS = Get-Content linkek_alatt.txt
If your file is a CSV file, then you'll need to reference the property name that matches the header of the URLs when using it in Invoke-WebRequest. E.g if it had a header of "URL":
Invoke-WebRequest -URI $item.URL
But I suspect this is not the case for you.

Resources