Powershell Auditing effective windows share permissions and outputting to CSV - windows

Powershell noob here. I'm trying to create a script that will take a list of users, a list of network shares, enumerate effective permissions for the user/share and output to CSV for audit purposes.
I've had success using GetPACEffectiveAccess from the PowerShellAccessControl Module on Technet gallery to do the enumeration, but am getting completely stuck on how to output this data to CSV how I want it.
The code I have is pretty simple:
$users=gc C:\scripts\users.txt
$shares=gc C:\scripts\shares.txt
foreach ($user in $users) {
foreach ($share in $shares) {
Get-PACEffectiveAccess -Path $share -Principal $user | select-object principal, accessmask, path | Export-Csv C:\scripts\EffectivePermissions\Audit.csv -append -NoTypeInformation}}
Since I have no idea how to do tables on StackOverflow (wow I am bad at this) I have attached a screenshot of the output I am getting from my simple script, and then the output I would like to get.
Any help would be much appreciated!
Thanks

After you gather the data, instead of outputting straight to the csv, you could add it to a two dimensional array, format it the way you'd like, and outfile it to a csv.

Related

How to find and delete duplicate Outlook emails in file explorer with PowerShell?

Please forgive me, I have little experience with PowerShell, but I know in theory what i need to do.
I have been given a list of 21,000 outlook emails and told to delete duplicates. The server uploaded these incorrectly somehow.The subject of the emails is a randomly generate string so is unique. I need to delete duplicates based on email size and manually opening the email to check that the content is the same. Rather than eyeballing them and comparing them manually which will take me approximately 25 years lol, does anyone know how to do this in PowerShell?
E.g. traverse through Outlook files line by line. IF one file size matches the previous, open both emails. AND Compare first line of email with both emails. IF they both match in terms of file size and content,delete one email. Surely this wouldn't be too difficult to do? Please help me, I cannot fathom looking at 21k emails!!
I've got powershell open and I navigated to the directory which hosts the 21k outlook emails. Please can someone help me? I know i am going to need some sort of loop in there and for 21k files it isn't going to be quick, but eyeballing them and doing it manually will take MUCH MUCH longer, the thought of manually doing it is giving me shivers...
Thanks! Much appreciated!
I am in powershell and navigated to the directory which hosts the 21k emails. I now need to find out how to traverse through line by line, find matching sizes and compare content, IF both are true then delete one file. I am not a programmer and I don't want to mess up by randomly winging it.
I'm not sure I understood everything but this might help you:
$Outlook = New-Object -ComObject Outlook.Application
$Namespace = $Outlook.GetNamespace("MAPI")
$Folder = $Namespace.GetDefaultFolder(6) # 6 is the index for the Inbox folder
$Emails = $Folder.Items
$Emails.Sort("[ReceivedTime]", $true)
$PreviousEmail = $null
foreach ($Email in $Emails) {
if ($PreviousEmail -ne $null -and $Email.Subject -eq $PreviousEmail.Subject -and $Email.ReceivedTime -eq $PreviousEmail.ReceivedTime) {
Write-Host "Deleting duplicate email with Subject:" $Email.Subject "and Received Time:" $Email.ReceivedTime
$Email.Delete()
}
$PreviousEmail = $Email
}
To run this tho, you need to change the directory to the outlook file locations. You can use "cd C:\PATH" or "Set-Location C:\PATH".
Eg:
cd C:\Users\MyUserName\Documents\Outlook\
Give it a try and let me know if works or it errors out. You might need to adjust some lines, I don't have outlook on my PC to test.
Also please do a backup/copy of the folder before running the script, in case it does delete emails it shouldn't.

Search membership queries in SCCM

More details on what we require:
We have a bunch of AD groups that may not be doing anything at all. What we would ideally like to do is somehow search SCCM for any usage of a particular AD group. Like if the group is used as part of a membership query anywhere.
For example I have tried the following in SCCM Powershell to look for any usage of the AD group sccm.minitablets :
Get-CMUserCollectionQueryMembershipRule | Where -Property RuleName -Like "%mini%"
I don't think the above command is of much use, as it has a required parameter that takes a specific collection name, whereas I need to search for any use of sccm.minitablets in any collection or any membership rule query across the board.
Is this even possible?
Was able to find a solution to this, for anyone else who might be interested:
Get-CMUserCollection | Get-CMUserCollectionQueryMembershipRule | Where -Property QueryExpression -Like "*mini*"
Get-CMDeviceCollection | Get-CMDeviceCollectionQueryMembershipRule | Where -Property QueryExpression -Like "*mini*"

Change Chrome Settings via Powershell

I want to make a script to change the default page zoom in Chrome, however I do not know where these options are stored.
I guess that I have to find an appropriate options text file, parse it, and then make a textual replacement there, using powershell in order to apply the changes.
I need to do it every time I plugin my laptop to an external monitor, and it is kinda annowying to do it by hand
Any ideas?
The default zoom level is stored in a huge JSON config file called Preferences, that can be found in the local appdata folder:
$LocalAppData = [Environment]::GetFolderPath( [Environment+SpecialFolder]::LocalApplicationData )
$ChromeDefaults = Join-Path $LocalAppData "Google\Chrome\User Data\default"
$ChromePrefFile = Join-Path $ChromeDefaults "Preferences"
$Settings = Get-Content $ChromePrefFile | ConvertFrom-Json
The default Page Zoom level is stored under the partition object, although it seems to store it as a unique identifier with some sort of ratio value, this is what it looks like with 100% zoom:
PS C:\> $Settings.partition.default_zoom_level | Format-List
2166136261 : 0.0
Other than that, I have no idea. I don't expect this to be a good idea, Chrome seems to update a number of binary values everytime the default files are updated, you might end up with a corrupt Preferences file
$Env:
Is a special PSdrive that contains many of the SpecialFolder Paths
$Env:LOCALAPPDATA
and
[Environment]::GetFolderPath( [Environment+SpecialFolder]::LocalApplicationData )
Yield the same result in addition to the rest of Mathias answer.

Powershell - filtering output of command

I'm quite new to powershell, but I've done a lot of batch scripting (yay for moving into the 'now!'). I'm trying to re-write my largest accomplishment in batch scripting into powershell, and right off the bat I'm hitting a bit of a wall.
What my original batch script did was install drivers for all of the detected system hardware. It did this by running devcon.exe and doing a search on the output, looking for VEN_ &DEV_ and trying to match it up with a comparison. This took a bit of time on slower computers (i3/Atom/slow AMD).
I stumbled across this command in powershell:
get-wmiobject -class CIM_VideoController PNPDeviceID
It spits out a list which contains just a few bits of info on the display adapter. The line in particular I'd like is the PNPDeviceID. I so far haven't had much luck in finding a way to manupulate the output to list just the VEN_ numbers.
Here's what I'd like to do: Run the command above, manipulate it so I get just the vendor number into one variable and the device number into another variable.
I tried doing this:
get-wmiobject -class CIM_VideoController PNPDeviceID | Select-String -Pattern "PNPDeviceID" -SimpleMatch
The problem I'm having is, it spits out nothing at all. I also have no clue on how to manipulate the output of that line further giving me only the 4 digit identifier of the 'VEN_' or the 'DEV_'.
Would anyone know how to do this?
I mean no disrespect, but this is pretty basic stuff. Have you considered finding a book (even an online one) and reading up on PowerShell? I've heard good things about Learning PowerShell In A Month Of Lunches.
As for your request, to get the four digit ID you could pipe that property's value to a regex match, and then output that match. It could be done like this:
$VidCardID = get-wmiobject -class CIM_VideoController PNPDeviceID | Where{$_.PNPDeviceID -match "VEN_(\d{4})"} | ForEach{$Matches[1]}
That will set $VidCardID to the 4 digit ID for the video card.
You can just do this:
$deviceID = (get-wmiobject -class CIM_VideoController).PNPDeviceID
the output of such objects are allways stored in a property which you can access by dot notation

automate creating sql statements using scripting tool

I often have a task a bit like this: insert a large number of users onto to the users table with similar properties. Not always that simple, but in general, list of strings -> list of corresponding sql statements.
my usual solution is this with the list of usernames in excel use a formula to generate a load of insert statements
=concatenate("insert into users values(username .......'",A1,"'.....
and then I fill down the formula to get all the insert rows.
This works but sometimes the statement is long, sometimes including a few different steps for each, and cramming it all into an excel formula and getting all the wrapping quotes right is a pain.
I'm wondering if there is a better way. What I really want is to be able to have a template file template txt:
insert into users
([username],
[company] ...
)
values('<template tag1>...
and then using some magic command line tool, to simply be able to type something like
command_line> make_big_file_using_template template.txt /values [username1 username2]
/output: bigfile.txt
and this gives me a big file with the template repeated for each username value with the tag replaced with the username.
So does such a command exist, or are my expectations of command line tools too high? Any freely available windows tool will do. I could whip up a c# program to do this in not too much time but I feel like there must be an easy to use tool out there already.
This is trivial using a Powershell script. PS allows inline variables in strings, so you could do something like:
$Tag1 = 'blah'
$Tag2 = 'foo'
$SQLHS = #"
INSERT INTO users
([username],
[company],...)
VALUES
('$tag1', '$tag2'...)
"#
set-content 'C:\Mynewfile.txt' -value $SQLHS
The #"...."# is a here-string, which makes it very easy to write readable code without escaping quotes and such.
The above could be very easily modified to accept parameters for the various tags and another for the output file, or to run for a set of values located in another .txt or .csv file as inputs.
EDIT:
To modify it to accept parameters, you can just add a param() block at top:
param($outfile, $tab1, $tab2, $tab3)
Then use those $variables in your script:
set-content "$outfile" -value $SQLHS

Resources