Phatmandrake

Forum Replies Created

Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • in reply to: How-to set Environment variables in PS7 MacOS #241190
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Thank You for responding! The module depends on a Binary. It’s actually this one: https://github.com/GoogleCloudPlatform/google-cloud-powershell it’s unfortunately not being curated, and there’s an issue where the Module is unable to see the gcloud python binary that it uses to bootstrap the PS Module. It’s using a Windows only method for updating the path. It would make sense for this use case that  gcloud is made available in the $env:PATH.

    Now there are ways of updating this to not need the gcloud binary entirely, but to get this thing up and running now I wanted to make an easy to edit suggestion.

    Details: https://github.com/GoogleCloudPlatform/google-cloud-powershell/issues/643

    • This reply was modified 2 months, 2 weeks ago by Phatmandrake.
    • This reply was modified 2 months, 2 weeks ago by Phatmandrake.
    • This reply was modified 2 months, 2 weeks ago by Phatmandrake.
    in reply to: could you please release my post from moderation? #241049
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    I would also like to request my post released from Moderation here as well:
    https://powershell.org/forums/topic/uploading-a-byte-array-using-invoke-restmethod/, no idea why it’s getting eaten, it happens so randomly.

    in reply to: How-to set Environment variables in PS7 MacOS #241043
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Thanks for sharing that. I am unable to locate that file so perhaps there is another source that is modifying $ENV:Path. Does anyone know how $PSProfile, this config file, and the existing ENV variables from MacOS Terminal interact? Trying to come up with the most stable way to modify $ENV:Path cross-platform for a module.

    • This reply was modified 2 months, 2 weeks ago by Phatmandrake.
    • This reply was modified 2 months, 2 weeks ago by Phatmandrake.
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Just supply a value to Param1, it will output as indicated. Is there a way to prevent parameter binding is the nature of the question though.

    in reply to: Download email attachments from a gmail account #237571
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    There’s a Commounity Module named PSGsuite that will make this simple.

    https://psgsuite.io/Initial%20Setup/

    Follow the instructions there to install the module and to authorize it to interact with your GSuite. Once you have it installed you’ll need to use 2 commands.

    Get-GSGmailMessage and Get-GSGmailMessageList

    Get-GSGmailMessageList will let you search for email stub records and obtain an ID to be used by Get-GSGmailMessage.

    Get-GSGmailMessage will let you retrieve the actual email based on the user account you want to access and the ID of the email.

    All together it will look something like:

    See examples here:
    https://psgsuite.io/Function%20Help/Gmail/Get-GSGmailMessageList/

    https://psgsuite.io/Function%20Help/Gmail/Get-GSGmailMessage/

    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Would there be a way to prevent the parameter binding from happening on param2 and param3? It inherently binds, is there a way to prevent it?

    • This reply was modified 2 months, 3 weeks ago by Phatmandrake.
    • This reply was modified 2 months, 3 weeks ago by Phatmandrake.
    in reply to: MSDS-userpasswordexpirytimecomputed?? #238403
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Well the password expiration is based on the policies set by your GPO, I don’t think it’s possible to arbitrarily add 30 days. You can at best “reset” the timer for when the password was last set, which would extend the password expiration for the interval defined by your domain.

    Although this isn’t really a Powershell related issue. You can use Set-ADUser to adjust the pwdlastset attribute. There are instructions for this elsewhere, but you should set it to 0 and then -1 .

    You may be able to use a fine-grained password policy to target those accounts you need to be extended for 30 days. I would not be able to instruct you on the specifics for how to do this though.

    • This reply was modified 2 months, 3 weeks ago by Phatmandrake.
    in reply to: Get-ADUser with Multiple filters #237967
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Accounts set to never expire will throw the error.

    in reply to: Get-ADUser with Multiple filters #237709
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    Your final Where-Object I believe may have been holding it up.

    Modified:

    Convert the exact name of the property. You have expiryDate, but the property is msDS-UserPasswordExpiryTimeComputed .

    I changed your conversion check as well so that it just does the conversion and compares it to the date using the same language in your Select-Object statement in case the conversion is failing with your method.

    Also if unless PowerShell is smart enough to combine those where-object filters (I do not know), you’re probably slowing you script down by calling it multiple time likes that.

    • This reply was modified 2 months, 4 weeks ago by Phatmandrake.
    • This reply was modified 2 months, 4 weeks ago by Phatmandrake.
    in reply to: How to get node’s information using compare-object? #237601
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    If I am understanding you correctly, then you want to know which Child Nodes of the FileName Nodes are not present in the Difference Object, but you also want to relate that to the Name attribute of the corresponding Filename parent node. If this is the case and you want to be able to actually work with Powershell Objects after the match, then I would convert your text XML to XElement Objects, and turn them into custom objects with the properties you need to examine, then compare those objects to each other.

    It’s important to note that when you use Compare-Object it simply looks for any identical matches, regardless of position unless you specify the SyncWindow parameter, which will then enforce position based comparison.

    Compare-Object Docs

    Compare-Object examines adjacent objects when it doesn’t find the object in the same position in a collection. The default value is  [Int32]::MaxValue, which means that  Compare-Object examines the entire object collection.

    I don’t know what other restraints you may be looking for in comparing the differences between your XML, but if you’re just looking to see which child nodes do not exist for parent nodes of type `FileName’, then the code above should work for you.

    • This reply was modified 2 months, 4 weeks ago by Phatmandrake. Reason: Grammar
    in reply to: How to get node’s information using compare-object? #237478
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    What are you trying to do once you have the difference?

    If you want to extract the value of the “Name” attribute from the node “FileName”, you will need to parse the information.

    Something like:

    Will output something like this:

    But it really depends on how you want the output to displayed/used. What do you want to do next with the information, or how do you want it specifically presented?

    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    I went on a journey for this one.

    TL;DR [XElement[]]$array=(0..2).foreach{[XElement]::new("Name","$_")} Specify the data type of the array using [XElement[]]. To use this with the .foreach() operator.

    Here is what I’ve learned.
    Is that same as this.

    At least in how the object appears when inspecting their members.

    If you assign either to the value of  [XElement](XName,Object[]), they will display malformed XML as demonstrated in the OP.
    However, if you extract each value of the collection, and enforce its type, it will interpret correctly, but this is only true if using ForEach-Object or foreach loop.
    From here I started playing around with the idea that the script block is causing the behavior. I stumbled across:
    This is when I realized
    Creates an array like foreach and ForEach-Object
    Creates a Collection like the .foreach() operator and .invoke()
    Some of this behavior can be explored here: https://powershell.one/tricks/performance/pipeline#how-it-works
    It was here I was the cusp of going ‘Too Deep”, at the very least what I now understood was:
    1. The .foreach() operator behaves like a scriptblock that is executed with the .invoke() method
    2. You cannot force the .foreach() operator to use the .InvokeReturnAsIs() method.
    3. The objects of the collection, when cast individually using ForEach-Object as [XElement] objects work as expected.
    Equipped with this knowledge I determined that the only way to use the .foreach() operator would be to somehow ensure
    the values being assigned to the variable would be passed explicitly as the [XElement] type…the light bulb went off.
    et voila
    It works as expected when you explicitly type the collection to expect [XElement] objects.
    (I actually thought of this a while ago but failed to recognize the [] syntax was necessary for doing this to arrays. :<)

    I do not know what to call the behavior that is causing objects processed using .invoke() on a script block to behave as if they are strings when passed as parameters to a method, but that appears to be the core problem.

    Ensuring that the elements of the collection are treated as their native type makes everything behave correctly. I believe the reason ForeEach-Object and foreach do not have this issue is because of how Powershell is handling the objects. They are assigning the objects as their native types without any ancillary behaviors.

    • This reply was modified 3 months ago by Phatmandrake.
    • This reply was modified 3 months ago by Phatmandrake. Reason: Grammar Level: Atrocious
    • This reply was modified 3 months ago by Phatmandrake.
    • This reply was modified 3 months ago by Phatmandrake.
    • This reply was modified 3 months ago by Phatmandrake.
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    At least I’m not crazy.

    • This reply was modified 3 months ago by Phatmandrake.
    • This reply was modified 3 months ago by Phatmandrake. Reason: Hunting for answers
    • This reply was modified 3 months ago by Phatmandrake.
    • This reply was modified 3 months ago by Phatmandrake.
    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    I stumbled across this: https://stackoverflow.com/questions/20803345/preventing-powershell-from-wrapping-value-types-in-psobjects, which got me thinking:

    So this is an example of a known method for preventing the issue of the text representation of the XElement obj, then using the same method to create another array, and running into the issue, then typing the pipeline variable while creating the array to prevent the issue.

    The same technique fails when using .foreach{} to build the source array.

    I think this demonstrates that a behavior with script blocks is causing the values to unwrap in some way? I dunno I’m butting up against the limits of my knowledge here. It’s like powershell implicitly understand it’s still of the same object type, so it’s displaying the correct properties to console when you print the Array, but when it’s apart of the pipeline it’s interpreting it as text because of something to do with script blocks??

    Edit:

    Look what a script block does:

    The output is also of type [System.Collections.ObjectModel.Collection`1], just like when you use the .foreach{} method. With this I can expand my search to the behaviors of script blocks, which are better documented. I am so close to an answer.

    Participant
    Topics: 6
    Replies: 15
    Points: 141
    Rank: Participant

    What I’ve figured out — There’s a question at the bottom.

    Background: I was using Invoke-RestMethod, 1st to update user data, and a 2nd time to read the user data.

    Update: Returned as single XMLElement object with a single property.
    Read: Returned a single XMLElement object with multiple properties.

    Problem: If the XMLElement object with a single property $Obj1 was sent to the console first, it would suppress the XMLElement Object with multiple properties $obj2 from displaying to the console, and $obj1 would display in a Format-Table style.

    If $obj2 were displayed first, $obj1 would also display in a Format-List style.

    Explanation:
    As explained here: https://devblogs.microsoft.com/powershell/how-powershell-formatting-and-outputting-really-works/

    Under the covers, every command entered in through the console host is piped to Out-Default.

    Out-Default looks at the <strong>FIRST OBJECT IN THE STREAM</strong> to determine how many properties the object has 5 or more properties, it sends the <strong>ENTIRE STREAM</strong> to Format-List, otherwise, it sends the <strong>ENTIRE STREAM</strong> to Format-Table. When it sends the stream to Format-Table, that command needs to generate columns.  It does this by looking at the properties of the <strong>FIRST OBJECT</strong> those become the columns.  If the first Object has 2 properties, youll get a 2 column table even if all the other objects in the stream have 10 properties.

    This explains why $obj1 would suppress the output of $obj2. Conversely, $obj2 which contained more than 5 or more properties was being sent to Format-List the behavior being:

    That if you and selected enough properties, Out-Default would have sent the object stream to Format-list and then each object would have all of its properties displayed.

    When $obj2 was called first, the behavior was that since $obj2 was sent to console with Format-List, based on the rules, all subsequent objects will be sent to console through Format-List, thus every property on each subsequent obj will be displayed rather than suppressed.

    To test this I create a test XMLElment Object with less than 5 properties, and it was indeed sent to console through Format-Table

    Solution:

    Obviously this isn’t ideal for objects with varying properties. The solution that I found was to send the objects to Out-Default.

    https://gist.github.com/phatmandrake/b688aaee6f4a8cae206337ac0a29fcfc

    By itself, this has the unintended consequence of removing the object from the pipeline, which isn’t conducive to passing data to another function, but it works if it’s end of the line.

    What I haven’t been able to figure out is why when $XMLSuccess is called twice, it only shows up once. The behavior mimics that the second output is suppressed. My guess is because it’s turning a property into a table “anonymously” it just isn’t aware it would be appropriate to merge the outputs since it doesn’t have anything to key off of being the same.

    • This reply was modified 3 months, 3 weeks ago by Phatmandrake.
    • This reply was modified 3 months, 3 weeks ago by Phatmandrake.
    • This reply was modified 3 months, 3 weeks ago by Phatmandrake.
    • This reply was modified 3 months, 3 weeks ago by Phatmandrake.
Viewing 15 posts - 1 through 15 (of 15 total)