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
Submarine Sandpaper
May 27, 2007


purge the klist and see if there are any other creds stored.

Submarine Sandpaper fucked around with this message at 18:18 on Dec 22, 2020

Adbot
ADBOT LOVES YOU

Wizard of the Deep
Sep 25, 2005

Another productive workday
How is the WinRM trusted hosts list distributed? Can you verify that they're the same on all servers?

Lum
Aug 13, 2003

Submarine Sandpaper posted:

purge the klist and see if there are any other creds stored.

Server has been rebooted twice since I initially posted this, so that would've cleared this.

I haven't set up a WinRM trusted hosts list that I know of. For all the other cross-domain servers it's just worked (before the domain trust was set up we were using CredSSP, and that still works)

i am a moron
Nov 12, 2020

"I think if there’s one thing we can all agree on it’s that Penn State and Michigan both suck and are garbage and it’s hilarious Michigan fans are freaking out thinking this is their natty window when they can’t even beat a B12 team in the playoffs lmao"

Lum posted:

Both servers are in the same subnet with the same firewall rules, and I can RDP to both of them using my DomainA\Admin account. Neither of them have domainA.local in their DNS search suffixes. Both of them are able to contact the DomainA DCs on the same port numbers (445 etc.)

WinRM config appears to be identical on both.

Server4 is supposed to be identical to Server3 as it's a failover copy.

Not sure what else to check, and unlike SSH, there's no verbose logging option I can find to see what's going on, just the generic error message.

Any idea where else to look?

The thing to me here is that you're getting told wrong username/password and not some other error message, which in a domain trust (to me) says something isn't reaching the other side of the trust properly. So on one of these without the explicit switch it's trying [username]@domainb.com instead of [username]@domaina.com. Or it's sending the right request to the wrong server. Something like that. You should actually be able to see that in the security logs afaik if it's either a username problem or a getting sent to the wrong domain problem. I'd bet cash money the credential switch will force it to use the correct domain which is why PS can sidestep the issue that way. RDP requires it anyways.

Are you totally, 100% sure DNS is the same on both of these server? No host file weirdness inserted for a poo poo Domain Trust deployment?

edit: There's always the possibility it's some weird PS bug, are the versions of PS the same on both of the servers? I kinda didn't think about that and have been assuming working server 1 and busted server 2 are identical in that regard.

i am a moron fucked around with this message at 18:44 on Dec 22, 2020

Lum
Aug 13, 2003

i am a moron posted:

The thing to me here is that you're getting told wrong username/password and not some other error message, which in a domain trust (to me) says something isn't reaching the other side of the trust properly. So on one of these without the explicit switch it's trying [username]@domainb.com instead of [username]@domaina.com. Or it's sending the right request to the wrong server. Something like that. You should actually be able to see that in the security logs afaik if it's either a username problem or a getting sent to the wrong domain problem. I'd bet cash money the credential switch will force it to use the correct domain which is why PS can sidestep the issue that way. RDP requires it anyways.

Are you totally, 100% sure DNS is the same on both of these server? No host file weirdness inserted for a poo poo Domain Trust deployment?

edit: There's always the possibility it's some weird PS bug, are the versions of PS the same on both of the servers? I kinda didn't think about that and have been assuming working server 1 and busted server 2 are identical in that regard.

PS version is 5.1.14009.1018 on both servers and the rest of $PSVersionTable is identical too. Hosts files are identical

The domain trust deployment was recent and was done by the guy above me, who seems to know his poo poo. As far as I'm aware it was pretty straightforward.

Security logs don't show any login failures, but that might be just because that's turned off, or I'm looking at the wrong one (looking in the event log)

Edit: So I turned on the failure audit policies for account login events, directory service access, logon events and privilege use and my attempts to log in still don't show in that log (though I can see unrelated failures)

Lum fucked around with this message at 11:35 on Dec 23, 2020

Toshimo
Aug 23, 2012

He's outta line...

But he's right!
I had to add some fields to the end of a section inside an old-school .INI file today and I wrote this code with equal parts shame and pride:

code:
$payload = foo`n"

switch((Get-Content -path $current_config_file -Raw).indexOf('[', (Get-Content -path $current_config_file -Raw).indexOf('[bar]')+1)) {

               -1 { $payload | Out-File $current_config_file -Append }

               Default { (Get-Content -Path $current_config_file -Raw).Insert($_,$payload) | Set-Content $current_config_file }

}

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams
Man, you are getting the content of that file way too many times.

Toshimo
Aug 23, 2012

He's outta line...

But he's right!

FISHMANPET posted:

Man, you are getting the content of that file way too many times.

Definitely, yeah. But it's inconsequential, so I didn't worry about it.

Potato Salad
Oct 23, 2014

nobody cares


Wizard of the Deep posted:

How is the WinRM trusted hosts list distributed? Can you verify that they're the same on all servers?

I lean on dsc with [insert any popular config/security management solution here]

SnatchRabbit
Feb 23, 2006

by sebmojo
Does anyone have a decent ps script for deploying a simple site to IIS? google had some mixed results dont need anything really fancy.

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


What the hell am I missing here? Is this some bizarre PowerShell Syntax thing I'm not understanding? I just want to write a small script that takes a large array and splits into smaller individual arrays.

code:
# Creating a new array
$InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
$chunkSize = 3
# Defining parts
$parts = [math]::Ceiling($inArray.Length / $chunkSize)
# Splitting the array to chunks of the same size
for($count=1; $count -le $chunksize; $count++)
{
    New-Variable -Name "OutputArray[$count]" -Value @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        ('$outputArray'+$count) += ,@($InputArray[$start..$end])
        #This doesn't work but might?
        #Set-Variable -Name "OutputArray[$count]" -Value ($outArray[$count]) += ,@($InputArray[$start..$end])
    }
}

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Crosby B. Alfred posted:

What the hell am I missing here? Is this some bizarre PowerShell Syntax thing I'm not understanding? I just want to write a small script that takes a large array and splits into smaller individual arrays.

code:
# Creating a new array
$InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
$chunkSize = 3
# Defining parts
$parts = [math]::Ceiling($inArray.Length / $chunkSize)
# Splitting the array to chunks of the same size
for($count=1; $count -le $chunksize; $count++)
{
    New-Variable -Name "OutputArray[$count]" -Value @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        ('$outputArray'+$count) += ,@($InputArray[$start..$end])
        #This doesn't work but might?
        #Set-Variable -Name "OutputArray[$count]" -Value ($outArray[$count]) += ,@($InputArray[$start..$end])
    }
}

The whole "dynamically creating new sequentially numbered variables" thing is a huge code smell. What are you actually trying to do here? The typical approach for this is to put them into a hash table (@{}) or into an array that you can iterate over. It looks to me like you want an array of arrays.

Toast Museum
Dec 3, 2005

30% Iron Chef

Crosby B. Alfred posted:

What the hell am I missing here? Is this some bizarre PowerShell Syntax thing I'm not understanding? I just want to write a small script that takes a large array and splits into smaller individual arrays.

code:
# Creating a new array
$InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
$chunkSize = 3
# Defining parts
$parts = [math]::Ceiling($inArray.Length / $chunkSize)
# Splitting the array to chunks of the same size
for($count=1; $count -le $chunksize; $count++)
{
    New-Variable -Name "OutputArray[$count]" -Value @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        ('$outputArray'+$count) += ,@($InputArray[$start..$end])
        #This doesn't work but might?
        #Set-Variable -Name "OutputArray[$count]" -Value ($outArray[$count]) += ,@($InputArray[$start..$end])
    }
}

If I'm reading this right, it seems like an issue with your OutputArray variable. Am I right in thinking that that New-Variable line is intended to index into a variable called OutputArray? That's not what it's doing; on the first iteration of that loop, for instance, it's creating a variable called OutputArray[1]; the [1] is part of the variable name you're creating with that command, not an index operator.

Later on, you've got ('$outputArray'+$count) += ,@($InputArray[$start..$end]), which has a few problems as well. You've got $outputArray in single quotes, so the string is literally $outputArray, not the value of the variable named outputArray. Swapping in double quotes wouldn't fix the bigger problem with that line, though: you're trying to assign a value to a string—not a variable of type string, but a string itself.

I hope this hasn't come off as overly harsh. I think there's probably a simpler way to do this, and I'll see what I can put together. To make sure I'm headed in the right direction, what are you trying to do with the smaller arrays that isn't working with the large one?

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


Toast Museum posted:

If I'm reading this right, it seems like an issue with your OutputArray variable. Am I right in thinking that that New-Variable line is intended to index into a variable called OutputArray? That's not what it's doing; on the first iteration of that loop, for instance, it's creating a variable called OutputArray[1]; the [1] is part of the variable name you're creating with that command, not an index operator.

Later on, you've got ('$outputArray'+$count) += ,@($InputArray[$start..$end]), which has a few problems as well. You've got $outputArray in single quotes, so the string is literally $outputArray, not the value of the variable named outputArray. Swapping in double quotes wouldn't fix the bigger problem with that line, though: you're trying to assign a value to a string—not a variable of type string, but a string itself.

I hope this hasn't come off as overly harsh. I think there's probably a simpler way to do this, and I'll see what I can put together. To make sure I'm headed in the right direction, what are you trying to do with the smaller arrays that isn't working with the large one?

I know doing something wrong with line 14 but I'm not sure how to fix it?

On line 10 I'm trying to create arrays determined by the $ChunkSize. For example, if I have a large array of 10,000+ objects, $ChunkSize is set to 10, this would create 10 arrays and they'd have a size of 1,000 each.

I guess what I am missing is how do I assign or modify my dynamic variables per line 14? I saw some earlier examples online that used the Set-Variable cmdlet but this still resulted in the same error and just left that section commented out.

Dirt Road Junglist
Oct 8, 2010

We will be cruel
And through our cruelty
They will know who we are
I'm still trying to figure out what your intent is with this.

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


Dirt Road Junglist posted:

I'm still trying to figure out what your intent is with this.

The dataset I'm working with is enormous but if I split it into smaller arrays to work with them in memory that'll work.

Submarine Sandpaper
May 27, 2007


Can you do what you want to do with the data using a -parallel switch anywhere without jumping through these hoops?

I see what you want to do and there's just gotta be a better way.

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


There's probably a better way but I'm still absolutely perplexed why I can't get 14 to function correctly.

Zaepho
Oct 31, 2013

Crosby B. Alfred posted:

The dataset I'm working with is enormous but if I split it into smaller arrays to work with them in memory that'll work.

Not sure this will buy you the performance you're looking for but here's what I've got. It seems to work but YMMV and so forth. I did use the PS7 ternary operator so you may have to tweak that if you're not using 7.

code:
# Creating a new array
[System.Collections.ArrayList] $InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
[int] $chunkSize = 3
# Splitting the array to chunks of the same size
[int] $I = 0

while ($InputArray.Count -gt 0) {
    [int] $count = $chunkSize -gt $InputArray.Count ? $InputArray.Count : $chunkSize
    [array] $Temp = @()
    foreach ($Item in $InputArray.GetRange(0, $count)) {
        $Temp += $Item
    }
    [void] $InputArray.RemoveRange(0, $count)
    $InputArray.TrimToSize()
       
    $VarName = "OutputArray" + $I++
    New-Variable -name $VarName -Value $Temp
}
$InputArray = $null

Write-host "Created $($I) arrays of $($ChunkSize) records"

$OutputArray0 | ft
Get-Variable

Methanar
Sep 26, 2013

by the sex ghost

Crosby B. Alfred posted:

The dataset I'm working with is enormous but if I split it into smaller arrays to work with them in memory that'll work.

Serialize your data and write it to a file and then only process what you can handle at a time.

Or just use a bigger machine.

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


Zaepho posted:

Not sure this will buy you the performance you're looking for but here's what I've got. It seems to work but YMMV and so forth. I did use the PS7 ternary operator so you may have to tweak that if you're not using 7.

code:
# Creating a new array
[System.Collections.ArrayList] $InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
[int] $chunkSize = 3
# Splitting the array to chunks of the same size
[int] $I = 0

while ($InputArray.Count -gt 0) {
    [int] $count = $chunkSize -gt $InputArray.Count ? $InputArray.Count : $chunkSize
    [array] $Temp = @()
    foreach ($Item in $InputArray.GetRange(0, $count)) {
        $Temp += $Item
    }
    [void] $InputArray.RemoveRange(0, $count)
    $InputArray.TrimToSize()
       
    $VarName = "OutputArray" + $I++
    New-Variable -name $VarName -Value $Temp
}
$InputArray = $null

Write-host "Created $($I) arrays of $($ChunkSize) records"

$OutputArray0 | ft
Get-Variable

I'm stuck with line 9... Trying to fix it myself, but how is this : operator supposed to function?

Zaepho
Oct 31, 2013

Crosby B. Alfred posted:

I'm stuck with line 9... Trying to fix it myself, but how is this : operator supposed to function?

code:
# [int] $count = $chunkSize -gt $InputArray.Count ? $InputArray.Count : $chunkSize

[int]$count = $chunkSize
if ($chunkSize -gt $InputArray.Count) {
     $count = $InputArray.Count
}

Toast Museum
Dec 3, 2005

30% Iron Chef

Crosby B. Alfred posted:

There's probably a better way but I'm still absolutely perplexed why I can't get 14 to function correctly.

As written,
code:
('$outputArray'+$count) += ,@($InputArray[$start..$end])
is sort of like writing
code:
2 = 2 + (3, 4, 5)
because the thing to the left of the equals sign isn't the type of thing you can assign values to. You can't assign a value to 2; it just is 2. On line 14, to the left of the equals sign, we've got
code:
('$outputArray'+$count)
Let's say the value of $count is 7. Because of the single quotes, you're not calling the variable $outputArray; you're writing a string with a value that is literally $outputArray7

Changing the single quotes to double quotes won't fix that line, though. The next hurdle is that the variable you're calling, $outputArray, hasn't been declared. On line 10,
code:
New-Variable -Name "OutputArray[$count]" -Value @()
I'm not sure whether this was the intent, but as written, the brackets in "OutputArray[$Count]" are part of the variable's name and do not represent an indexer. As above, let's say that the value of $count is 7. Line 10 is creating a variable named OutputArray[7]. If that was intentional, I'd recommend not doing that; because of the special characters in the variable's name, you'd have to write ${OutputArray[7]} to call the variable, which will get old in a hurry.

From a performance standpoint, I'm not sure whether creating a bunch of variables to contain subsets of a large collection provides any benefit over just using the indexer on the big collection to call ranges of indices. It really does seem like there's got to be a better way to handle this than generating a bunch of new variables, but I know that "how do I do thing"/"you shouldn't do thing" is an frustrating conversation, so here's a lightly-tested function for splitting up a collection and assigning each subset to a variable:

code:
function Split-CollectionToVariables
{
    [CmdletBinding()]
    param 
    (
        # Receives the collection from the pipeline.
        [Parameter(
            Mandatory = $true
        )]
        [System.Collections.IList]
        $Collection,

        # How many pieces to split the collection into.
        [Parameter(
            Mandatory = $true
        )]
        [int]
        $ChunkCount,

        # The new variable names will be this plus a pseudo-index.
        [Alias("Name")]
        [Parameter(
            Mandatory = $true
        )]
        [string]
        $VariableNameRoot,

        # Choose whether to overwrite existing variables
        [Parameter(
            Mandatory = $false
        )]
        [switch]
        $Force
    )
    
    begin
    {
        $chunkSize = [math]::Ceiling($Collection.Length / $ChunkCount)
        Write-Verbose -Message "Chunk size: $chunkSize"
        if ($ChunkCount -gt $chunkSize) {throw "Collection contains fewer than $ChunkCount items"}
    }
    
    process 
    {
        for($($chunk = 0; $startIndex = 0);
            $($chunk -lt $ChunkCount);
            $($chunk += 1; $startIndex += $chunkSize))
        {
            $endIndex = $startIndex + $chunkSize -1
            
            Write-Verbose -Message "Chunk: $Chunk"
            Write-Verbose -Message "startIndex: $startIndex"
            Write-Verbose -Message "endIndex: $endIndex"
            Write-Verbose -Message "VariableName: $VariableNameRoot$chunk"

            New-Variable -Name "$VariableNameRoot$chunk" -Value $Collection[$startIndex..$endIndex] -Scope Global -Force:$Force
        }    
    }
    
    end {}
}

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


Zaepho posted:

code:
# [int] $count = $chunkSize -gt $InputArray.Count ? $InputArray.Count : $chunkSize

[int]$count = $chunkSize
if ($chunkSize -gt $InputArray.Count) {
     $count = $InputArray.Count
}

I'm still getting weird errors with this but the next script functions as expected or there's something up with my workstation.

New-Variable : Cannot create variable OutputArray4172 because variable capacity 4096 is exceeded for this scope.

Toast Museum posted:

As written,
code:
('$outputArray'+$count) += ,@($InputArray[$start..$end])
is sort of like writing
code:
2 = 2 + (3, 4, 5)
because the thing to the left of the equals sign isn't the type of thing you can assign values to. You can't assign a value to 2; it just is 2. On line 14, to the left of the equals sign, we've got
code:
('$outputArray'+$count)
Let's say the value of $count is 7. Because of the single quotes, you're not calling the variable $outputArray; you're writing a string with a value that is literally $outputArray7

I'm referencing a freaking string named $outputarray7 :psyduck:

Is it not possible to reference dynamic variables in PowerShell in way I'm attempting to do here? I was under the impression that it possible to merely return something like $OutputArray1, $OutputArray2, $OutputArray3, etc.

Toast Museum posted:

Changing the single quotes to double quotes won't fix that line, though. The next hurdle is that the variable you're calling, $outputArray, hasn't been declared. On line 10,
code:
New-Variable -Name "OutputArray[$count]" -Value @()
I'm not sure whether this was the intent, but as written, the brackets in "OutputArray[$Count]" are part of the variable's name and do not represent an indexer. As above, let's say that the value of $count is 7. Line 10 is creating a variable named OutputArray[7]. If that was intentional, I'd recommend not doing that; because of the special characters in the variable's name, you'd have to write ${OutputArray[7]} to call the variable, which will get old in a hurry.

From a performance standpoint, I'm not sure whether creating a bunch of variables to contain subsets of a large collection provides any benefit over just using the indexer on the big collection to call ranges of indices. It really does seem like there's got to be a better way to handle this than generating a bunch of new variables, but I know that "how do I do thing"/"you shouldn't do thing" is an frustrating conversation, so here's a lightly-tested function for splitting up a collection and assigning each subset to a variable:

My intent here was to reference one of my earlier dynamically created variables and populate it with the contents of $InputArray. This answers my earlier question, I could just use the ugly syntax of${OutputArray[$count]} on line 14 but what's weird is that I'm getting the same error messages as Zaepho's script but the one you created runs flawlessly.

Performance or best practice standards aside, this should still work... right?

code:
# Creating a new array
$InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
$chunkSize = 3
# Defining parts
$parts = [math]::Ceiling($inputArray.Length / $chunkSize)
# Splitting the array to chunks of the same size
for($count=1; $count -le $chunksize; $count++)
{
    New-Variable -Name "OutputArray[$count]" -Value @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        ${OutputArray[$count]} += ,@($InputArray[$start..$end])
    }
}
code:
Cannot create variable parts because variable capacity 4096 is exceeded for this scope.
Anyhow, thanks for the help. I'm not familiar with the last two examples but I am going reverse engineer or study these tonight. :haw:

Edit - I had the wrong variable name earlier, I'm no longer getting the variable capacity error but none of my dynamic variables are being populated.

Gucci Loafers fucked around with this message at 15:43 on Feb 23, 2021

Toast Museum
Dec 3, 2005

30% Iron Chef

Crosby B. Alfred posted:

I'm still getting weird errors with this but the next script functions as expected or there's something up with my workstation.

New-Variable : Cannot create variable OutputArray4172 because variable capacity 4096 is exceeded for this scope.

It's news to me, but apparently a given scope (or at least the global scope) can only handle 4096 declared variables at a time in Windows PowerShell. I need to stare at the script that's throwing the error a bit more to see exactly where the problem is, but I suspect that $ChunkSize is involved. Your script uses that variable to define how many chunks there are, rather than how big each chunk is, which is kinda misleading, and I have a feeling there's a mix-up over that detail at some point.

quote:

I'm referencing a freaking string named $outputarray7 :psyduck:

Is it not possible to reference dynamic variables in PowerShell in way I'm attempting to do here? I was under the impression that it possible to merely return something like $OutputArray1, $OutputArray2, $OutputArray3, etc.

You can do that, and I think you're just a little hung up on the syntax on variables and index operators. I hope this clears it up some:

code:
# A variable named Foo.
$Foo

# A variable named Foo5.
$Foo5

# A variable named Foo, which contains a collection, in which we are calling the value at index 5.
$Foo[5]

# From the collection held in variable Foo, we are calling the item whose index matches the value of a variable named i.
$Foo[$i]

# Using Get-Variable to retrieve a variable named Foo.
# Retrieves the name and the value.
Get-Variable -Name "Foo"

# Getting the value of a variable named Foo5, when the value of variable i is 5.
$i = 5
Get-Variable -Name "Foo$i" -ValueOnly

# Getting the value of a variable named Foo5 using the values of two other variables.
$Bar = "Foo"
$i = 5
Get-Variable -Name "$Bar$i" -ValueOnly
In a nutshell:
  • Unless someone is jumping through hoops, the [] after a variable is an index operator, not part of the variable's name.
  • Don't make variables with non-alphanumeric characters in their names unless you absolutely must, which isn't the case here.
  • The -Name parameter on Get-Variable and Set-Variable accepts a string. Whatever that string is, that's what the variable name is going to be. If you stick a variable in the -Name parameter, the new variable's name will be the value of that other variable.

Toast Museum fucked around with this message at 07:06 on Feb 23, 2021

Pile Of Garbage
May 28, 2007



Crosby B. Alfred posted:

I'm still getting weird errors with this but the next script functions as expected or there's something up with my workstation.

New-Variable : Cannot create variable OutputArray4172 because variable capacity 4096 is exceeded for this scope.

:lol: I've never seen that error before and did not know that there was a per-scope variable limit. IMO this is a very clear sign that you're not approaching things in maybe the worst way possible.

Edit: if you want to just get chunks of an array you can use Select-Object with the First and Skip parameters. For example:

code:
PS C:\> $Array = 1..10
PS C:\> $Array
1
2
3
4
5
6
7
8
9
10
PS C:\> $Array | Select-Object -First 5
1
2
3
4
5
PS C:\> $Array | Select-Object -First 5 -Skip 5
6
7
8
9
10
You could incorporate that into a loop to process individual chunks of an array.

Pile Of Garbage fucked around with this message at 10:42 on Feb 23, 2021

Toshimo
Aug 23, 2012

He's outta line...

But he's right!
Why would someone do this?

code:

$some_list = "foo", "bar", "baz" -split"," | ?{$_}

mystes
May 31, 2006

Toshimo posted:

Why would someone do this?

code:
$some_list = "foo", "bar", "baz" -split"," | ?{$_}
The last part will remove empty strings. You're splitting each input string on "," flattening the output, and then removing empty strings.

Edit: Or if you mean "why would someone write code like this" rather than "what does it do" then I guess the answer is "lol powershell" :shrug:?

mystes fucked around with this message at 20:28 on Feb 23, 2021

Toshimo
Aug 23, 2012

He's outta line...

But he's right!

mystes posted:

The last part will remove empty strings. You're splitting each input string on "," flattening the output, and then removing empty strings.

Edit: Or if you mean "why would someone write code like this" rather than "what does it do" then I guess the answer is "lol powershell" :shrug:?

Yeah, I mean they literally did that on a line to feed it into a foreach loop instead of:

$somelist = ("foo","bar","baz")

Zaepho
Oct 31, 2013

Toshimo posted:

Why would someone do this?

Copy Pasta. Probably got some examples from different places to do what they thought they needed to do and just altered it to fit rather than understanding the right way to do it.

Toshimo
Aug 23, 2012

He's outta line...

But he's right!

Zaepho posted:

Copy Pasta. Probably got some examples from different places to do what they thought they needed to do and just altered it to fit rather than understanding the right way to do it.

Yeah, their entire script is full of choice tidbits like this, which is why someone brought it to me to decipher. It'll probably get rubber stamped to go to prod anyway, but at least someone is asking questions.

FISHMANPET
Mar 3, 2007

Sweet 'N Sour
Can't
Melt
Steel Beams

Crosby B. Alfred posted:

I'm still getting weird errors with this but the next script functions as expected or there's something up with my workstation.

New-Variable : Cannot create variable OutputArray4172 because variable capacity 4096 is exceeded for this scope.


I'm referencing a freaking string named $outputarray7 :psyduck:

Is it not possible to reference dynamic variables in PowerShell in way I'm attempting to do here? I was under the impression that it possible to merely return something like $OutputArray1, $OutputArray2, $OutputArray3, etc.


My intent here was to reference one of my earlier dynamically created variables and populate it with the contents of $InputArray. This answers my earlier question, I could just use the ugly syntax of${OutputArray[$count]} on line 14 but what's weird is that I'm getting the same error messages as Zaepho's script but the one you created runs flawlessly.

Performance or best practice standards aside, this should still work... right?

code:
# Creating a new array
$InputArray = Get-Eventlog -LogName Application
# Defining the chunk size
$chunkSize = 3
# Defining parts
$parts = [math]::Ceiling($inputArray.Length / $chunkSize)
# Splitting the array to chunks of the same size
for($count=1; $count -le $chunksize; $count++)
{
    New-Variable -Name "OutputArray[$count]" -Value @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        ${OutputArray[$count]} += ,@($InputArray[$start..$end])
    }
}
code:
Cannot create variable parts because variable capacity 4096 is exceeded for this scope.
Anyhow, thanks for the help. I'm not familiar with the last two examples but I am going reverse engineer or study these tonight. :haw:

Edit - I had the wrong variable name earlier, I'm no longer getting the variable capacity error but none of my dynamic variables are being populated.

OK, I think there's some things you're missing about variables.
One thing you may have figured out now but to be clear, in PowerShell, something like $variable indicates you're referencing a variable with the name variable. The $ isn't part of the variable name, it just indicates to the interpreter that you're referencing a variable.
Also, something to know about variables in strings. When you put a string in single quotes ('my great variable $var') Powershell does no interpolation, the value will literally be 'my great variable $var. If you put the same string in double quotes, it will interpolate the variable, so if $var has a value of foo then "my great variable $var" will be my great variable foo
So others have mentioned but in your latest example let's look at this line:
code:
New-Variable -Name "OutputArray[$count]" -Value @()
I think what you're intending is that you want to reference the $count'th element in an array named $OutputArray but using New/Get/Set-Variable is going to look for a variable literally of that name, so you're actually creating a variables named $OutputArray[1], $OutputArray[2], etc. So I suspect your variables are getting populated, but then you're trying to reference that variable by saying $tempvar = $OutputArray[1] and that's looking for the element in position 1 (by the way, array indexing starts at 0 in powershell) in a variable that doesn't exist called $OutputArray (because you never created $OutputArray, you created $OutputArray[1], $OutputArray[2], etc) and you get a null reference error. You can actually just run the command Get-Variable with no parameters and it will show you all the variables you've created and you'll probably see all these individual $OutputArrays. And that's why in your example you've had to wrap your variable reference in curly braces, they're telling the interpreter to not do any interpreting with those brackets, just take the string exactly as is between the brackets. That also means, it's not going to even interpret $count so you're setting a variable over and over named literally OutputArray[$count] (very rude of Powershell to even allow you to put some of these characters in variable names).

Because of the your code is written, it runs, but it just keeps stuffing all the values into OutputArray[$count] rather than OutputArray[1], OutputArray[2], etc

I felt generous, and also to actually understand what you were trying to do, I rewrote this in a couple ways. First, actually creating an array of arrays. No need mess around with dynamically defining variable names, though you're treating the array in a very non-powershell way so this is kind of weird, having to pre-initialize the output array so that you can actually insert into it.
code:
$outputarray = [Object[]]::new($chunksize+1)
for($count=1; $count -le $chunksize; $count++)
{
    $OutputArray[$count] = @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        $OutputArray[$count] += ,@($InputArray[$start..$end])
    }
}
This will produce a single variable OutputArray, which is an array of 3 elements, and each element is an array with $parts number of events.

If you're truly interested in Dynamic variables, well here you go. This is very messed up because what you're trying to do is again... very messed up
code:
for($count=1; $count -le $chunksize; $count++)
{
    New-Variable -Name "OutputArray$count" -Value @()
    #$OutputArray[$count] = @()
    for($i=0; $i -le $parts; $i++){
        $start = $i*$chunkSize
        $end = (($i+1)*$chunkSize)-1
        Set-Variable -Name "OutputArray$count" -Value ((Get-Variable -Name "OutputArray$count").Value += ,@($InputArray[$start..$end]))
    }
}
That will produce 3 new variables, OutputArray1, OutputArray2, and OutputArray3, each variable having an array with $parts number of events.

mllaneza
Apr 28, 2007

Veteran, Bermuda Triangle Expeditionary Force, 1993-1952




FISHMANPET posted:

Get-Variable

Oh hey, thing I can use in my lunch n' learn in a couple weeks.

I'm doing an introductory thing, so I'll start with some simple console tricks and show off how it remembers your variables. Then some Active Directory stuff, ending up with adding a user to a group, then make it easier to type with variables, then the Get-Content/foreach() combo. After that, spend as much time as I've got to turn it into a real script with parameters and functions for logging, timestamps, and verifying that everything that was supposed to happen got done.

Basically taking people from maybe knowing a few commands to being able to turn a one-liner into a resuable script.

Pile Of Garbage
May 28, 2007



mllaneza posted:

Oh hey, thing I can use in my lunch n' learn in a couple weeks.

I'm doing an introductory thing, so I'll start with some simple console tricks and show off how it remembers your variables. Then some Active Directory stuff, ending up with adding a user to a group, then make it easier to type with variables, then the Get-Content/foreach() combo. After that, spend as much time as I've got to turn it into a real script with parameters and functions for logging, timestamps, and verifying that everything that was supposed to happen got done.

Basically taking people from maybe knowing a few commands to being able to turn a one-liner into a resuable script.

A good thing to add at the end might be a brief mention of how all objects are .NET classes and how to discover functionality using Get-Member, the GetType() method and Googling class names. Also make sure they know about the PowerShell "about" topics. They're core to defining how PowerShell behaves and yet a lot of people I meet who're just starting out have no idea that they exist.

mllaneza
Apr 28, 2007

Veteran, Bermuda Triangle Expeditionary Force, 1993-1952




Pile Of Garbage posted:

A good thing to add at the end might be a brief mention of how all objects are .NET classes and how to discover functionality using Get-Member, the GetType() method and Googling class names. Also make sure they know about the PowerShell "about" topics. They're core to defining how PowerShell behaves and yet a lot of people I meet who're just starting out have no idea that they exist.

Some of that's getting saved for the "intermediate" session, but thanks !

TITTIEKISSER69
Mar 19, 2005

SAVE THE BEES
PLANT MORE TREES
CLEAN THE SEAS
KISS TITTIESS




I need to determine which mailboxes (of disabled users) are forwarding to oldmanager, and then either turn off the forwarding or change it to newmanager - which one of those it will be is TBD. This is on-prem Exchange 2016, how do I begin?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

TITTIEKISSER69 posted:

I need to determine which mailboxes (of disabled users) are forwarding to oldmanager, and then either turn off the forwarding or change it to newmanager - which one of those it will be is TBD. This is on-prem Exchange 2016, how do I begin?

Google and the documentation are usually good starting points. Have you tried anything or done any research on your own about how to accomplish your goal?

Inspector_666
Oct 7, 2003

benny with the good hair
It should also be pretty straightforward, use Get-ADUser with whatever filter you need to grab your disabled users to generate the list of mailboxes to check, then use Get-Mailbox to find which ones are forwarding to the oldmanager.

I'd probably put that output into a CSV to easily see what you're working with and then you can run the final script against it, which should just be a Set-Mailbox command.

Xarn
Jun 26, 2015
I have a stupid problem: I have two json documents from different sources, and I want to dump both of them into a text file. That part is easy enough.

The hard (?) and stupid part is that the end result should be two .json files that can be textually diffed against each other, to see if the two sources of truth disagree. This means that I need the output normalized, e.g. by writing the keys in a lexicographical order...


Is there a simple way to do that?

Adbot
ADBOT LOVES YOU

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Xarn posted:

I have a stupid problem: I have two json documents from different sources, and I want to dump both of them into a text file. That part is easy enough.

The hard (?) and stupid part is that the end result should be two .json files that can be textually diffed against each other, to see if the two sources of truth disagree. This means that I need the output normalized, e.g. by writing the keys in a lexicographical order...


Is there a simple way to do that?

Can't you just sort the two files regardless of syntactic correctness and then compare line by line?

Something like this:
code:
$file1 = @'
{
"hello": "world",
"foo": "bar"
}
'@

$file2 = @'
{
"foo": "bar",
"hello": "world"
}
'@

$file1Lines = ($file1 -split [Environment]::NewLine | sort-object) | % { $_.TrimEnd(',') } 
$file2Lines = ($file2 -split [Environment]::NewLine | sort-object) | % { $_.TrimEnd(',') } 

foreach ($line in $file1Lines) {
    $file2Lines -contains $line
}

New Yorp New Yorp fucked around with this message at 16:38 on Mar 5, 2021

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