Powershell Match Statement from list of Files - powershell

I am searching through a directory looking for files that only contain the number 0.
I have used the code:
$fileList = Select-String -Path c:\cnt\*.txt -pattern "0"
And it outputs a list, such as:
C:\cnt\itm123.txt:1:0
c:\cnt\itm1234.txt:1:0
c:\cnt\itm123456.txt:1:0
I need to only extract the itm### but the total numbers in the filename can range from 3-6.
Using the example above I need a list that looks like:
itm123
itm1234
itm123456
Once I get that I will run each through a SQL query, but I am not worried about that part.

The Select-String cmdlet returns a list of Microsoft.PowerShell.Commands.MatchInfo objects. If you call the Get-Member cmdlet with the parameter -MemberType Properties you will get a list of all exposed properties:
Name MemberType Definition
---- ---------- ----------
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property string Filename {get;}
IgnoreCase Property bool IgnoreCase {get;set;}
Line Property string Line {get;set;}
LineNumber Property int LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property string Path {get;set;}
Pattern Property string Pattern {get;set;}
In this case, you are looking for the Filename property. So if you execute
Select-String -Path c:\cnt\*.txt -pattern "0" | select FileName
you will get all filenames:
itm123.txt
itm1234.txt
itm123456.txt
Now all you have to do is to remove the file extension which can be done using the .NET method GetFileNameWithoutExtension:
Select-String -Path c:\cnt\*.txt -pattern "0" |
ForEach-Object { [io.path]::GetFileNameWithoutExtension($_.FileName)}
Output:
itm123
itm1234
itm123456

Related

Exporting a Powershell object containing multiple sets to CSV

I have a Powershell object which is the result of DSInternals Test-PasswordQuality cmdlet that I'd like to use as a Power BI dataset; it's a bunch of sets of user accounts, ex.
PS C:\> $result | get-member
TypeName: DSInternals.PowerShell.PasswordQualityTestResult
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
AESKeysMissing Property System.Collections.Generic.ISet[string] AESKeysMissing {get;set;}
ClearTextPassword Property System.Collections.Generic.ISet[string] ClearTextPassword {get;set;}
DefaultComputerPassword Property System.Collections.Generic.ISet[string] DefaultComputerPassword {get;set;}
DelegatableAdmins Property System.Collections.Generic.ISet[string] DelegatableAdmins {get;set;}
DESEncryptionOnly Property System.Collections.Generic.ISet[string] DESEncryptionOnly {get;set;}
DuplicatePasswordGroups Property System.Collections.Generic.IEnumerable[System.Collections.Generic.ISet[string]] DuplicatePasswordGroup…
EmptyPassword Property System.Collections.Generic.ISet[string] EmptyPassword {get;set;}
Kerberoastable Property System.Collections.Generic.ISet[string] Kerberoastable {get;set;}
LMHash Property System.Collections.Generic.ISet[string] LMHash {get;set;}
PasswordNeverExpires Property System.Collections.Generic.ISet[string] PasswordNeverExpires {get;set;}
PasswordNotRequired Property System.Collections.Generic.ISet[string] PasswordNotRequired {get;set;}
PreAuthNotRequired Property System.Collections.Generic.ISet[string] PreAuthNotRequired {get;set;}
SmartCardUsersWithPassword Property System.Collections.Generic.ISet[string] SmartCardUsersWithPassword {get;set;}
WeakPassword Property System.Collections.Generic.ISet[string] WeakPassword {get;set;}
PS C:\> $result | select LMHash
LMHash
------
{a_user, another_user, yet_another_user…}
I'd like to export this to one csv where each array is its own column. If I simply do
$result | export-csv .\result.csv -NoTypeInformation
I do get a separate column for each set, but then just the the Set object type under each, ex.
How can I get a list of users, with each user in it's own cell, like this?
UPDATE
As an example, one of the elements of $result.PSObject.Properties is:
MemberType : Property
Value : {user, another_user, another_user…}
IsSettable : True
IsGettable : True
TypeNameOfValue : System.Collections.Generic.ISet`1[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral,
PublicKeyToken=7cec85d7bea7798e]]
Name : LMHash
IsInstance : True
So I think I need to iterate through the $result.PSObject.Properties for the column names and then also iterate through essentially $(result.PSObject.Properties).Value to get the users into separate cells in the csv. But doing them via index, i.e. $(result.PSObject.Properties).Value[1] results in the property types in the csv instead of the actual values. I tried nested foreach loops but still couldn't quite crack it.
Given the scenario, you can use a loop (in this case I will use a for loop to demonstrate this) to iterate through the listings using a PSCustomObject:
$maxCount = [math]::Max($result.LMHash.Count,$result.ClearTextPassword.Count)
for ($i = 0; $i -lt $maxCount; $i++)
{
[PSCustomObject]#{
LMHash = $result.LMHash[$i]
ClearTextPassword = $result.ClearTextPassword[$i]
} #| Export-Csv -Path ".\result.csv" -Append -NoTypeInformation
}
$maxCount will be the max number of iterations the for loop should iterate to; given those two properties of LMHash, and ClearTextPassword.

Power Shell Output filter

I'm using the comand Get-AzresourceGroup. The ouput of that command is information about ResourID, Tags, Resource group name etc. of all resource groups in Azure. I want to store in a variable all the names of the resource groups, I do not need the other information. Is there a way I can do that?
Thank you!
Comand Output
From the Get-AzResourceGroup documentation, you can simply reference only the Resource Group Name :
$groups = (Get-AzResourceGroup).ResourceGroupName
Or using the CLI, and extracting from the JSON:
$group = az group list | ConvertFrom-Json
$group | Select-Object -Property Name
Try piping the output from Get-AzResourceGroup to Select-Object and use the -Property parameter to specify the property/properties to select.
$rgs = Get-AzResourceGroup | Select-Object -Property ResourceGroupName
Your will results should look something like this.
$rgs
ResourceGroupName
-----------------
ddo-06212021-1
ddo-06212021-2
ddo-06212021-3
cloud-shell-storage-eastus
If you're unsure what properties are available to select from the results of Get-AzResourceGroup, you can first pipe the output to Get-Member, and view the available properties.
Get-AzResourceGroup | Get-Member
TypeName: Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Location Property string Location {get;set;}
ManagedBy Property string ManagedBy {get;set;}
ProvisioningState Property string ProvisioningState {get;set;}
ResourceGroupName Property string ResourceGroupName {get;set;}
ResourceId Property string ResourceId {get;set;}
Tags Property hashtable Tags {get;set;}
TagsTable Property string TagsTable {get;}
Links
Select-Object - learn.microsoft.com
Get-Member - learn.microsoft.com

how to find and store filenames in a list with PowerShell?

In the context of emulating the tree command, looking at files in sub-directories:
posh>
posh> $dir = "/home/nicholas/Calibre Library/Microsoft Office User/549 (1476)"
posh>
posh> Get-ChildItem -Path $dir –File
Directory: /home/nicholas/Calibre Library/Microsoft Office User/549 (1476)
Mode LastWriteTime Length Name
---- ------------- ------ ----
----- 2/20/2021 3:22 AM 159883 549 - Microsoft Office User.txt
----- 2/20/2021 2:13 AM 351719 cover.jpg
----- 2/20/2021 2:31 AM 1126 metadata.opf
posh>
How is the filename above assigned to a variable?
An array or list of String would be sufficient. But how is the "Name" above captured? Or, for that matter, the "Directory" or other attributes?
Most cmdlets in powershell return objects. Objects have properties. When you do Get-ChildItem that returns a collection of DirectoryInfo and FileInfo objects each with their own set of properties, albeit very similar.
The following command will retrieve all the files in the path $dir as FileInfo objects and will add them to an array contained in $files
$files = Get-ChildItem -Path $dir –File
Now, each object in $files is a FileInfo object which contain properties like Name, BaseName, Directory, LastWriteTime, CreationTime, Extension, and many more. To see what properties exist on an object you can pipe | the object to Get-Member
$files | Get-Member
This will provide some information about the type of object and its properties and methods. The following list has been truncated for brevity. You may and should try this on your own.
TypeName: System.IO.FileInfo
Name MemberType Definition
---- ---------- ----------
AppendText Method System.IO.StreamWriter AppendText()
CopyTo Method System.IO.FileInfo CopyTo(string destFileName), System.IO.FileInfo CopyTo(string destFileName, ...
Create Method System.IO.FileStream Create()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
CreationTime Property datetime CreationTime {get;set;}
CreationTimeUtc Property datetime CreationTimeUtc {get;set;}
Directory Property System.IO.DirectoryInfo Directory {get;}
DirectoryName Property string DirectoryName {get;}
Exists Property bool Exists {get;}
Extension Property string Extension {get;}
FullName Property string FullName {get;}
Length Property long Length {get;}
Name Property string Name {get;}
Now that you know what properties exist on the objects you may access them like so
PS C:\temp> $files.Name
test.ps1
test.xml
test1.xlsx
test2.csv
testemail.csv
testout.xml
testxml.xml
write.xml
or
PS C:\temp> $files.FullName
C:\temp\test.ps1
C:\temp\test.xml
C:\temp\test1.xlsx
C:\temp\test2.csv
C:\temp\testemail.csv
C:\temp\testout.xml
C:\temp\testxml.xml
C:\temp\write.xml
You can also pipe the objects to Select-Object to get modified objects back with only the properties you want or even custom (calculated properties).
$files | Select-Object Name, CreationTime, #{Label='Age'; Expression= {((Get-Date).Date - ($_.CreationTime).Date).Days}}
Name CreationTime Age
---- ------------ ---
test.ps1 19.02.2021 10:56:25 3
test.xml 14.02.2021 19:28:19 8
test1.xlsx 04.02.2021 19:31:54 18
test2.csv 04.02.2021 23:00:46 18
testemail.csv 03.02.2021 15:35:43 19
testout.xml 14.02.2021 19:32:03 8
testxml.xml 14.02.2021 19:33:41 8
write.xml 08.02.2021 17:26:40 14
Now that is only a small intro to Powershell. There is really much much more to it. I've seen your other posts and see that you are interested. There are many really good tutorials out there. I recommend that you have a look at a few of them and see all that there really is to learn. For starters, have a look at this one about objects in powershell

powershell pull variable from inf file

$OEM = "N/A"
$data = (get-content C:\Windows\INF\OEM27.inf | select-string "10.18.10.4358")
if ($data -eq "DriverVer=12/21/2015,10.18.10.4358"){
$OEM = $true}
else {$OEM = $false}
echo $data
echo $OEM
So I'm trying to test this small code out before adding it to my larger script. However $OEM keeps coming up a False even though $data comes back as DriverVer=12/21/2015,10.18.10.4358. Not sure what I'm over looking but it is pretty late at night. Any help would be appreciated. ^^"
The object returned by Select-String isn't a string. It is a MatchInfo:
C:\> $data | Get-Member
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RelativePath Method string RelativePath(string directory)
ToString Method string ToString(), string ToString(string directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property string Filename {get;}
IgnoreCase Property bool IgnoreCase {get;set;}
Line Property string Line {get;set;}
LineNumber Property int LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property string Path {get;set;}
Pattern Property string Pattern {get;set;}
You can get to the line it matches on with the Line property. So change your code to this:
if ($data.Line -eq "DriverVer=12/21/2015,10.18.10.4358")
However, I don't think that is very robust code because INI files can have spaces around the "=". This would be better:
if ($data.Line -match "DriverVer\s*=\s*12/21/2015,10.18.10.4358")
I think your code is a bit over complicated. You could replace the whole thing with this:
$OEM = [bool](Select-String "DriverVer\s*=\s*12/21/2015,10.18.10.4358" C:\Windows\INF\OEM27.inf)

How to retrieve email alias and CN for everyone in an AD group using PowerShell

I am using PowerShell with the Quest AD cmdlets.
I can use the Get-QADGroupMember cmdlet to get a list of everyone in a given group. So far so good but I would like to get their email alias as well. All that is returned currently is something like:
Name Type DN
---- ---- --
Jane Doe User CN=Jane Doe,OU=Employee,DC=companyname,DC=com
Job Blow User CN=Joe Blow,OU=Employee,DC=companyname,DC=com
I tried using get-qaduser with the -includeallproperties flag but I still only get the above fields returned and I don't know how to get at the returned data which the documentation says is cached on the computer.
Any help would be appreciated.
UPDATE
I ended up using "select" similar to below:
$everyone = Get-QADGroupMember "All employees" | select firstname, lastname, email
And that got everything I needed into an array of hashtables. At that point it is easy to do whatever is needed by iterating through everyone with code like:
for ($i=0; $i -le $everyone .length-1; $i++)
{
write-host $everyone[$i].email
}
Took me forever to find the "." notation for pulling specific values out of the hashtable. I did text parsing and that worked but I knew that couldn't be the right way of doing it and eventually found documentation on the dot notation. I hope documenting that here saves someone else some time!
Are you sure it really doesn't return that information? Have you tried piping the command into Get-Member or Format-List -Force *? PowerShell can be configured to only show a few properties of items and not all which might be the case here.
You can select properties using Select-Object or just select if you konw they are there, even though PowerShell doesn't display them by default:
Some-Command | select Name, Type, DN, SomeOtherProperty
You can see this for example with Get-ChildItem too:
PS Home:\> gci *.ps1
Directory: C:\Users\Joey
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2011-04-27 18:50 169 format.ps1
-a--- 2011-04-26 18:36 1064 Untitled1.ps1
-a--- 2011-04-27 18:41 69 x.ps1
-a--- 2011-04-23 19:58 91 y.ps1
The normal invocation only yields four properties: Mode, LastWriteTime, Length and Name. However, there are plenty more, as Get-Member shows.
PS Home:\> gci *.ps1|gm -MemberType Property
TypeName: System.IO.FileInfo
Name MemberType Definition
---- ---------- ----------
Attributes Property System.IO.FileAttributes Attributes {get;set;}
CreationTime Property System.DateTime CreationTime {get;set;}
CreationTimeUtc Property System.DateTime CreationTimeUtc {get;set;}
Directory Property System.IO.DirectoryInfo Directory {get;}
DirectoryName Property System.String DirectoryName {get;}
Exists Property System.Boolean Exists {get;}
Extension Property System.String Extension {get;}
FullName Property System.String FullName {get;}
IsReadOnly Property System.Boolean IsReadOnly {get;set;}
LastAccessTime Property System.DateTime LastAccessTime {get;set;}
LastAccessTimeUtc Property System.DateTime LastAccessTimeUtc {get;set;}
LastWriteTime Property System.DateTime LastWriteTime {get;set;}
LastWriteTimeUtc Property System.DateTime LastWriteTimeUtc {get;set;}
Length Property System.Int64 Length {get;}
Name Property System.String Name {get;}
Rememember that select-object strips down the object and generates new ones.
So in this example:
$test = get-qaduser atestuser | select-object name
$test will be a PSCustomObject (System.Object) containing only the name.
What do you want do do with the data? Output to the console...to a file?
I would do something like this:
get-qadgroupmember "domain users" | format-table name, displayname, email
Or
get-qadgroupmember "domain users" | select-object name, displayname, email | Export-Csv c:\acsvfile.csv