Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
12 rats tied together
Sep 7, 2006

That seems really terrible, but if I were forced at gunpoint to write and maintain something like that I would probably just use
code:
Switch ($serverclass) {
    "Win2008db" { expression }
    "Win2012db" { expression }
}
But there is almost certainly a better way to do this that doesn't involve a powershell script with a gigantic switch statement. Firewall rules management is probably (definitely) better handled by something like ansible.

Adbot
ADBOT LOVES YOU

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin

Reiz posted:

That seems really terrible, but if I were forced at gunpoint to write and maintain something like that I would probably just use
code:
Switch ($serverclass) {
    "Win2008db" { expression }
    "Win2012db" { expression }
}
But there is almost certainly a better way to do this that doesn't involve a powershell script with a gigantic switch statement. Firewall rules management is probably (definitely) better handled by something like ansible.

Definitely! I'm in a big room mostly full of people writing code for Puppet.

The idea though is that instead of updating the code every time things change, you can update configuration files.
A huge chain of if-then statements is much harder to maintain.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
I'm writing some performance monitoring scripts, stuff to check CPU, Memory, etc.

I can think of a few ways to do any check, but I'm wondering if there's already some good work done on this subject that I can just use.

I'm thinking of using performance counters so I can get a better idea of performance over time if I'm only checking once every five minutes.

Any ideas on how to approach this?

Judge Schnoopy
Nov 2, 2005

dont even TRY it, pal
I've got an odd powershell question that I can't seem to find an answer on.

When I run this locally on HostName:
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall | foreach-object {Get-ItemProperty $_.PsPath}

I get the exact results I'm looking for. When I try the same command from my computer using "Invoke-Command -computer HostName {*above command*}" it says the path does not exist.

Except I know it exists because I can run the same thing from the target computer and get my result. Is there a limitation with remote powershell that can't access this registry path? Or do I need to edit the HKCU path to specifically aim it at that computer?

Walked
Apr 14, 2003

Judge Schnoopy posted:

I've got an odd powershell question that I can't seem to find an answer on.

When I run this locally on HostName:
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall | foreach-object {Get-ItemProperty $_.PsPath}

I get the exact results I'm looking for. When I try the same command from my computer using "Invoke-Command -computer HostName {*above command*}" it says the path does not exist.

Except I know it exists because I can run the same thing from the target computer and get my result. Is there a limitation with remote powershell that can't access this registry path? Or do I need to edit the HKCU path to specifically aim it at that computer?

My gut is that the Invoke-Command isnt picking up on the pipeline properly.
Can you try this command via invoke-command, but without the "| foreach-object.... " ?

nielsm
Jun 1, 2009



Judge Schnoopy posted:

I've got an odd powershell question that I can't seem to find an answer on.

When I run this locally on HostName:
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall | foreach-object {Get-ItemProperty $_.PsPath}

I get the exact results I'm looking for. When I try the same command from my computer using "Invoke-Command -computer HostName {*above command*}" it says the path does not exist.

Except I know it exists because I can run the same thing from the target computer and get my result. Is there a limitation with remote powershell that can't access this registry path? Or do I need to edit the HKCU path to specifically aim it at that computer?

HKCU (HKEY_CURRENT_USER) only really exists for interactive logon sessions. When you remote to another machine, which user is "current"?

If you want to enumerate Uninstall entries for local user accounts on another machine, your best bet is really to force the system user account service to load the profile. That should in turn cause the user hive to appear under HKEY_USERS (named after the account SID), where you might then be able to access it with remoting.

As for forcing the user account service to load a profile, remotely, no idea.

Judge Schnoopy
Nov 2, 2005

dont even TRY it, pal
Well this got more interesting as I did more digging. I ran:
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion
On HostName and got a list of subkeys.

Then I ran:
Invoke-Command -computer Hostname {Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion}
And got the same list of subkeys, except the uninstall subkey is missing. It's the only difference between the two outputs.

Maybe Microsoft blocks access to the uninstall subkey when using powershell remote, maybe it's a bug, but it's a huge hindrance to my script here.

nielsm
Jun 1, 2009



Are you sure it's the same user hive you're looking at with both commands? Really sure?

Judge Schnoopy
Nov 2, 2005

dont even TRY it, pal

nielsm posted:

Are you sure it's the same user hive you're looking at with both commands? Really sure?

...

gently caress

Thank you. Digging in to other subkeys I'm finding subtle differences in values.

So now I'm back to square 1 where I cannot check which of the 4 OneClick applications are installed on remote machines. I guess I could just shotgun the uninstall string and let it error out if the application isn't there.

nielsm
Jun 1, 2009



Judge Schnoopy posted:

...

gently caress

Thank you. Digging in to other subkeys I'm finding subtle differences in values.

So now I'm back to square 1 where I cannot check which of the 4 OneClick applications are installed on remote machines. I guess I could just shotgun the uninstall string and let it error out if the application isn't there.

Try, on the remote (I think it must be done on the remote at least) to set up HKEY_USERS as a PSDrive and then check what profiles are available there:

code:
New-PSDrive -Provider Registry -Root HKEY_USERS -Name HU
Get-ChildItem HU:\ -ErrorAction Ignore | where name -NotLike "*_Classes"
You'll want the Ignore error action since some of the profiles may just not be accessible for your user, and filter off the Classes hives too. Normal user accounts should then all have a SID of the form "S-1-5-21-*".

Just keep in mind this will only get you user hives for profiles that are loaded on that machine right now. Usually means you'll see them for system accounts, service accounts, whatever account you're remoting in with, and then any users that have logged locally on to the machine after last boot. (Profiles of logged off users tend to stay loaded, at least for a while.)

beepsandboops
Jan 28, 2014
Is there a good way to like schedule or delay something in Powershell on the magnitude of days?

Like if I get notice that an employee is leaving in a few weeks, would I be able to run a script to disable their mailboxes on their last day? Or what do most people typically do?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

beepsandboops posted:

Is there a good way to like schedule or delay something in Powershell on the magnitude of days?

Like if I get notice that an employee is leaving in a few weeks, would I be able to run a script to disable their mailboxes on their last day? Or what do most people typically do?

Windows task scheduler

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
Scheduled tasks can be created with
New-ScheduledTask

Check the examples.

vanity slug
Jul 20, 2010

beepsandboops posted:

Is there a good way to like schedule or delay something in Powershell on the magnitude of days?

Like if I get notice that an employee is leaving in a few weeks, would I be able to run a script to disable their mailboxes on their last day? Or what do most people typically do?

Set-ADAccountExpiration?

Swink
Apr 18, 2006
Left Side <--- Many Whelps
Ask me about expiring staff who decide to stay on for a few extra days.

Roargasm
Oct 21, 2010

Hate to sound sleazy
But tease me
I don't want it if it's that easy

beepsandboops posted:

Is there a good way to like schedule or delay something in Powershell on the magnitude of days?

Like if I get notice that an employee is leaving in a few weeks, would I be able to run a script to disable their mailboxes on their last day? Or what do most people typically do?

PS has a built in job creator but I don't trust it. Windows Task Scheduler GUI, set your trigger, and the action is launch c:\windows\system32\powershellv1\powershell.exe, arguments "-file 'c:\path\to\script.ps1' -NoProfile -ExecutionPolicy Bypass -Noninteractive"

beepsandboops
Jan 28, 2014

Jeoh posted:

Set-ADAccountExpiration?
From what I understand, Exchange mailboxes aren't disabled when AD accounts are disabled the same way it syncs up with deleted AD accounts.

We've generally not deleted user accounts in AD as a rule (it seems many orgs do this), so I can use Set-ADAccountExpiration, but then have to circle back around for the Exchange mailbox anyway.

I might be spending too much time trying to automate this, but learning about the Powershell side of scheduled tasks has been interesting.

Swink
Apr 18, 2006
Left Side <--- Many Whelps
The disable-mailbox exchange cmdlet removes the mailbox but only disables the AD user.

*please check this is correct before running it.

Judge Schnoopy
Nov 2, 2005

dont even TRY it, pal
I made a script to install Flash Plugin, which works great when downloading the file from the internet.

Our remote branches have a 1.5 meg pipe to us for internet access. Downloading that file takes 5 minutes and bogs operations for the duration. I'd love to host the install file on a local PC at each branch, then have the script copy the file from that local PC to the target PC.

Everything I do to try reaching another PC results in "Cannot find path". I'm clearly doing something wrong. I can't even do a "Get-ChildItem -Path \\server\share" successfully.

Here's the rundown:
Script asks for target PC. Regex match sets $location to one of 4 UNC paths, depending on $target. Invoke-Command is passed through a PSSession to that computer, with the rest of the install script.
code:
If ($target -match "branch"){
$location = "\\branch1\c$\Software\install_flash_player_20_plugin.msi"}

$s = New-PSSession -computername $target

Invoke-Command -Session $s -Scriptblock{

Copy-Item $location "$Env:Temp\install_flash_player_20_plugin.msi"

$installPlugin = Get-WmiObject -List 'Win32_Product'
$installPlugin.Install($Env:Temp\install_flash_player_20_plugin.msi) | Out-Null
}
No matter what I try to make $location point to, if it's not on the local machine I always get a Cannot Find Path error. Like mentioned, I've also tried \\server\share\flash\plugin.msi (which has wide open permissions for all domain users, and I'm running the script with domain admin privileges).

I can't find what I'm missing here. Any help?

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
I'm not sure, but I think when you start doing sessions like that, sometimes permissions get all screwed up.

There are ways to fix it, but maybe try making a folder that's shared to "Everyone" and see if you can access it. That would prove it's a credential issue.

Doug
Feb 27, 2006

This station is
non-operational.
I'm trying to create a script that will take 1-3 inputs from a user and then search mailboxes for emails that match that criteria and ultimately delete from the user's mailbox and forward to a blackhole mailbox. I can make it work if I run -SearchQuery with 1 variable, but things get a little wacky when I try to do a search query with 3 variables. I found some information about variables not exapanding within scriptblocks, so I've tried to fix that with the $search variable but now I'm getting a "keyword isnt supported" error so I'm certain I've just mangled the formatting. Anyone got any tips?
code:
#normalize function strips wildcard characters before searching exchange to prevent accidental deletion
function normalize($str){
    $str = $str -replace '[*]',''
    $str = $str -replace '[?]',''
    return $str
    }
#validate email format based on Regex
function validate($eml){
    $EmailRegex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$'
    if ( $eml -match $EmailRegex ){
        return $eml
    }
    else{ return 0 }
}
#initialize variables to wildcards    
$choice = 0
$sender = '*'
$subject = '*'
$body = '*'

while ($choice -ne 10){
    Clear
    Write-Host ************Malicious Email Removal Tool************
    Write-Host Search criteria:
    Write-Host 1- Sender 
    Write-Host 2- Subject
    Write-Host 3- Body
    Write-Host 4- Review information
    Write-Host 5- Remove evil
    Write-Host 9- Clear entries
    Write-Host 10- Quit 
    $choice = Read-Host Enter your selection 
    
    If ($choice -eq 1) {
        Write-Host Enter the senders email address `(Wildcard characters are not allowed and will be stripped`)
        $sender = Read-Host
        $sender = normalize($sender)
        if ( validate($sender) ) {continue}
        else {
            Write-Host You entered: $sender which is not a valid email address. Please re-enter.
            Read-Host Press enter}
        }
    elseif ($choice -eq 2) {
        Write-Host Enter some or all of the subject line `(Wildcard characters are not allowed and will be stripped`)
        $subject = Read-Host
        $subject = normalize($subject)
        }
    elseif ($choice -eq 3){
        Write-Host Enter the body of the email or key phrases contained in the email `(Wildcard characters are not allowed and will be stripped`)
        $body = Read-Host
        $body = normalize($body)
        }
    elseif ($choice -eq 4){
        Write-Host Sender: $sender
        Write-Host Subject: $subject
        Write-Host Body: $body
        Read-Host Press ENTER
        }
    elseif ($choice -eq 5){
       #check to make sure values were set for all variables to prevent full wildcard search
	 if (($sender -eq '`*') -AND ($body -eq '`*') -AND ($subject = '`*'))
        {
            Write-Host "You didn't enter any search criteria"
            Read-Host "Press enter to continue"
            continue
        }
        $search = [scriptblock]::create("'sender:$sender AND body:`*$body`* AND subject:`*$subject`*'")
        Get-Mailbox | Search-Mailbox -SearchQuery $search  -TargetMailbox "blackhole" -TargetFolder "Evil"
        Read-host "Press enter to continue"
        }
    elseif ($choice -eq 9){
        $sender = '*'
        $subject = '*'
        $body = '*'
        }
        
    elseif ($choice -eq 10) {continue}
    else {
        Write-Host Invalid selection
        Read-Host Press enter to continue}
    }
Ultimately you should be able to put in full or partial entries for any of the fields and get the search to run.

Edit: Also- search-mailbox creates a really obnoxious folder structure for each of the results it finds, showing which mailbox and folder the email was found in. Is there a way to just send the email to the blackhole without creating that directory structure? The thought of catching like 100 emails and having a huge tree for all of them seems crazy.

Doug fucked around with this message at 22:38 on Feb 17, 2016

Judge Schnoopy
Nov 2, 2005

dont even TRY it, pal

Dr. Arbitrary posted:

I'm not sure, but I think when you start doing sessions like that, sometimes permissions get all screwed up.

There are ways to fix it, but maybe try making a folder that's shared to "Everyone" and see if you can access it. That would prove it's a credential issue.

Don't worry I'm a loving idiot and wasn't in an elevated powershell console.

Rule 1 of powershell: If you know you're running as admin and something obvious doesn't work, you're wrong and need to close / reopen the console as admin.

Doug
Feb 27, 2006

This station is
non-operational.
Follow up from my earlier post. I've fixed the query kind of. If I populate all 3 variables the search completes without issue but I'm still having trouble doing partial searches. If I search for full email(which I've required) , full subject and partial body, I get the desired result. If I search partial subject, suddenly it fails. I'm wondering if the search I want to do is even possible with KQL. I want to take input from the user and do a search but the input could be the beginning, middle, end or complete of any or all of the three fields. Is this possible or am I just outside of Powershell scope at this point?

MF_James
May 8, 2008
I CANNOT HANDLE BEING CALLED OUT ON MY DUMBASS OPINIONS ABOUT ANTI-VIRUS AND SECURITY. I REALLY LIKE TO THINK THAT I KNOW THINGS HERE

INSTEAD I AM GOING TO WHINE ABOUT IT IN OTHER THREADS SO MY OPINION CAN FEEL VALIDATED IN AN ECHO CHAMBER I LIKE

Doug posted:

Follow up from my earlier post. I've fixed the query kind of. If I populate all 3 variables the search completes without issue but I'm still having trouble doing partial searches. If I search for full email(which I've required) , full subject and partial body, I get the desired result. If I search partial subject, suddenly it fails. I'm wondering if the search I want to do is even possible with KQL. I want to take input from the user and do a search but the input could be the beginning, middle, end or complete of any or all of the three fields. Is this possible or am I just outside of Powershell scope at this point?

I would think you could use a wildcard in some way to do it, I'm not well versed in powershell but in prior coding experience I've used wildcards to do what you're describing. Depending on your dataset you could do *string* or something similar although it could return too many results....

Gothmog1065
May 14, 2009
Alright goons, I'm diving into Powershell head first.

Right now what I'm trying to do is a short script that checks if a computer is online via DNS, and eventually write to an output file (Haven't quite gotten to that point yet). So far what I've gotten stuck on a bit is test-connection:

PowerShell code:
## Pull computer list from CSV file
$csv = import-csv "H:\My Documents\Python\test.csv"

foreach($csv_line in $csv)
{
    $ctag = $csv_line.ctag
    $name = $csv_line.name

    # Attempt to reduce timeout on test-connection
    $count = 1
    $timeout = 1000
    $filter = 'Address="{0}" and timeout={1}' -f $ctag, $timeout
   
    #$test_ping = test-connection $ctag -Count 1 -ErrorAction SilentlyContinue
    $test_ping = Get-WmiObject -Class Win32_PingStatus -Filter $filter | Select-Object ResponseTime
    echo $test_ping

    if ($test_ping) {echo "Success"}else{echo "Fail"}
#
#        $LatestFolder = Get-ChildItem \\$ctag\c$\Users | sort lastwritetime -desc | select -first 1
#        $Username = $LatestFolder.name
#        echo "CTAG: $ctag, SS Owner: $name, last logged in user:  $username"
#        } else {echo "Host is unreachable through DNS"}

}
Basically i'm trying to shorten the timeout to less than 4 seconds (1 preferably). With the code I found, I can change the timeout, but it always passes test. Is there a different conditional I should be using, or am I going to have to stick with 4s timeouts, or go a totally different route?

As you can see I have the original $test_ping to see what I"m doing.

Gothmog1065 fucked around with this message at 15:18 on Feb 22, 2016

nielsm
Jun 1, 2009



Alternative solution, perhaps: Use the Start-Job and Wait-Job cmdlets to create a job for each computer on your list, and have them run in parallel.
Look up the about_Jobs help file to get some examples.

If you go that way, you should probably not use "echo" or similar direct output, but rather have the jobs return one or more objects with the result, which you can then collate and process afterwards.

Doug
Feb 27, 2006

This station is
non-operational.

MF_James posted:

I would think you could use a wildcard in some way to do it, I'm not well versed in powershell but in prior coding experience I've used wildcards to do what you're describing. Depending on your dataset you could do *string* or something similar although it could return too many results....

Yeah, I'm familiar with wildcards and you would think that would work, but it seems the problem is due to using KQL for the search. In KQL the * character is used as a prefix delimiter. So things like foo* work when searching for things that start with 'foo' but *bar doesn't work because it looks for the stuff behind the * as the prefix. Actually, reading this technet again, I see it says explicitly that suffix matching is not supported.

Roargasm
Oct 21, 2010

Hate to sound sleazy
But tease me
I don't want it if it's that easy
If you let the error continue without stopping, $test_ping is probably returning as true even if it fails. You want the error to break the process, and then you can catch it and return something else

PHP code:
$csv = import-csv c:\files\mycomps.csv

foreach ($line in $csv) {

try {
test-connection $_.compName -Count 1 -ErrorAction Stop
echo "$_.compName is valid" >> c:\files\goodDNS.txt
}

catch {
echo "$_.compName is not valid" >> c:\files\badDNS.txt
}
}

Gothmog1065
May 14, 2009

Roargasm posted:

If you let the error continue without stopping, $test_ping is probably returning as true even if it fails. You want the error to break the process, and then you can catch it and return something else

PHP code:
$csv = import-csv c:\files\mycomps.csv

foreach ($line in $csv) {

try {
test-connection $_.compName -Count 1 -ErrorAction Stop
echo "$_.compName is valid" >> c:\files\goodDNS.txt
}

catch {
echo "$_.compName is not valid" >> c:\files\badDNS.txt
}
}

I turned it back to the commented out test_ping (Test connection) for now. It takes a bit but works properly.

Gothmog1065 fucked around with this message at 15:24 on Feb 23, 2016

Methanar
Sep 26, 2013

by the sex ghost

Gothmog1065 posted:

Alright goons, I'm diving into Powershell head first.

Right now what I'm trying to do is a short script that checks if a computer is online via DNS, and eventually write to an output file (Haven't quite gotten to that point yet). So far what I've gotten stuck on a bit is test-connection:



I actually did something very similar to this once. I made a powershell module for testing DNS. Then in another script I called the defined functions and would run hostnames/IPs against the functions.

http://pastebin.com/j4xFDEkF The DNS functions module.
http://pastebin.com/mmDUiTPA The script

My way was kind of slow and not that great but you might be able to somehow parallelize the DNS readings with a workflow. Maybe something like

Methanar fucked around with this message at 20:26 on Feb 23, 2016

Gothmog1065
May 14, 2009
Well, I think I got something that works reasonably well now. The csv-export could be handled much better (IE correctly) but when trying to build the variable to export, it does really stupid things.

PHP code:
## Pull computer list from CSV file
$csv = import-csv "H:\My Documents\Python\test.csv"
$output = "h:\My Documents\Python\results.txt"

echo "ctag,Username" | out-file $output

foreach($csv_line in $csv)
{
    $ctag = $csv_line.ctag

    $test_ping = test-connection $ctag -Count 1 -erroraction SilentlyContinue

    if ($test_ping) {
        
        $LatestFolder = Get-ChildItem \\$ctag\c$\Users | sort lastwritetime -desc | select -first 1
        $Username = $LatestFolder.name

        if ($Username -eq "Public") {
            $ADName = "No User"
        } else {
            $ADName = Get-ADUser -Identity $Username
            $ADName = $ADName.Name
        }

    } else {
        $ADName = "ERROR"
    }

    $result = "$ctag,$ADName"
    echo $result | Out-File $output -Append
}

$NewInfo = $output | Export-Csv -path "h:\My Documents\Python\Results.csv"
Are there any other glaring issues that anyone sees? How is the formatting in general?

12 rats tied together
Sep 7, 2006

There's a -quiet parameter for test-connection that might be more appropriate here.

Venusy
Feb 21, 2007
You also don't need to construct the output CSV manually if you don't want to, and echo isn't normally necessary, as it's just an alias for Write-Output.
code:
## Pull computer list from CSV file
$csv = import-csv "H:\My Documents\Python\test.csv"
$output = "h:\My Documents\Python\results.csv"

$results = foreach ($csv_line in $csv) {
    $ctag = $csv_line.ctag
    $test_ping = test-connection $ctag -Count 1 -Quiet
    
    switch ($test_ping) {
        $true {
            $LatestFolder = Get-ChildItem \\$ctag\c$\Users | sort lastwritetime -Descending | select -first 1
            $Username = $LatestFolder.name
            
            if ($Username -eq "Public") {$ADName = "No User"} 
            else {
                $ADName = Get-ADUser -Identity $Username
                $ADName = $ADName.Name
            }

        }
        $false {$ADName = "ERROR"}
    }
    
    $result = [PSCustomObject]@{
        CTAG = $ctag
        UserName = $ADName
    }
    $result
}

$results | Export-Csv -path $output
This lets you manipulate the $results variable directly in PowerShell later if you want to.

As you get more used to PowerShell, you might be able to use Get-CimInstance Win32_UserProfile (or Get-WmiObject Win32_UserProfile) to see who's currently logged in. There have been a few cases at work where the user has subsequently been renamed, so I had to get their SID and run Get-ADUser based on that.

Irritated Goat
Mar 12, 2005

This post is pathetic.
I'm looking to do archives of OneDrive accounts via Powershell for work purposes. Is it even possible? I know you can do a Get-ChildItem on it and download 1 file or possible 1 folder worth of items but I'm trying to automate it.
I'm just not skilled enough in the scripting department to accomplish it. Any pointers would help a ton.

Gothmog1065
May 14, 2009

Venusy posted:

You also don't need to construct the output CSV manually if you don't want to, and echo isn't normally necessary, as it's just an alias for Write-Output.


This lets you manipulate the $results variable directly in PowerShell later if you want to.

As you get more used to PowerShell, you might be able to use Get-CimInstance Win32_UserProfile (or Get-WmiObject Win32_UserProfile) to see who's currently logged in. There have been a few cases at work where the user has subsequently been renamed, so I had to get their SID and run Get-ADUser based on that.
When I was trying to build the $result variable and display it, it did weird things (like repeat the entire list over and over), but I was probably doing it wrong. I'm still not sure how the square brackets work, I looked it up and it mentioned arrays, but some of the other examples I was looking at didn't have it set to a variable.

They just changed the web filter (to Websense) at work, which means SA is blocked because it's "tasteless". It's a pretty apt description, but it really hurts my ability to ask questions here. I'll definitely work your information into my updated code. I'm pulling directly from a spreadsheet and am trying to some basic file error handling.

Thanks for all the help!

Gothmog1065
May 14, 2009
Okay, edit for clarity. here is my full code.

Basically what is happening is the entire list is shown as it is created which is fine, but when the csv is created, it only creates a .csv with three lines:

#TYPE System.Management.AUtomation.PSCustomObject
CTAG,Username
C27999,ERROR

The last one is the last hostname (which is unpingable.

Any ideas?

E2: helps if I add all of the suggested code. Thanks guys.

Gothmog1065 fucked around with this message at 17:38 on Mar 1, 2016

beepsandboops
Jan 28, 2014
How would you completely remove a group's permissions from a folder? This is the closest I have:
code:
$acl = Get-Acl -Path $directory

$removePermissions = New-Object System.Security.AccessControl.FileSystemAccessRule("contoso\group","Read",,,"Allow")
$acl.RemoveAccessRuleAll($removePermissions)

Set-Acl -Path $directory -AclObject $acl
Which comes close but still lists the group as having permissions, although very limited:

Zaepho
Oct 31, 2013

beepsandboops posted:

How would you completely remove a group's permissions from a folder? This is the closest I have:
code:
$acl = Get-Acl -Path $directory

$removePermissions = New-Object System.Security.AccessControl.FileSystemAccessRule("contoso\group","Read",,,"Allow")
$acl.RemoveAccessRuleAll($removePermissions)

Set-Acl -Path $directory -AclObject $acl
Which comes close but still lists the group as having permissions, although very limited:


Try something along the lines of:
code:
 
$Group = 'contoso\group'
$acl = Get-Acl -Path $directory
$acl[0].Access | where-object -property IdentityReference -eq -value $group | %{
	$acl.RemoveAccessRuleAll($_)
}

The trick here is that when you got the ACL for the directory, there is a property called Access that contains all of the access rules. Filter that for the one you want and then use it to do the removal.

Your code is trying to build a NEW access rule to overwrite the existing one rather than actually removing it.

As an aside, you may want to do some checking to see if it's an inherited permission before you remove it, just in case.

beepsandboops
Jan 28, 2014

Zaepho posted:

As an aside, you may want to do some checking to see if it's an inherited permission before you remove it, just in case.
Earlier in the script I have this:
code:
$acl.SetAccessRuleProtection($true,$true)
Which I understand to mean that it inherits permissions but converts them into explicit permissions that can be altered. Am I right in that?

Adbot
ADBOT LOVES YOU

Zaepho
Oct 31, 2013

beepsandboops posted:

Earlier in the script I have this:
code:
$acl.SetAccessRuleProtection($true,$true)
Which I understand to mean that it inherits permissions but converts them into explicit permissions that can be altered. Am I right in that?

Do you actually WANT to block inheritance? if so, then no issue and converting everything to explicit is fine. If you don't mean to block permission inheritance then you might rework that a bit (maybe only block inheritance when you encounter an instance of inherited permissions than causes you an issue).

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply