itglue / automation

A place for IT Glue's user community to learn ways of automating their documentation.
Apache License 2.0
99 stars 33 forks source link

Update does not work - creates a new Flexible Asset each time #1

Open digitaltruss opened 6 years ago

digitaltruss commented 6 years ago

I have tried running both the Active Directory and File Share scripts on a few servers and if I run them multiple times on the same server, new assets are created instead of updating an existing asset.

First run: Active Directory flex asset configuration file found! No organization id was specified in the config file, attempting an auto-match based on the name: (redacted) Auto-match successful. Updating config file with organization id. No flexible asset id was found... creating a new flexible asset.

data

@{id=redacted; type=flexible-assets; attributes=}

Second run: Active Directory flex asset configuration file found! No flexible asset id was found... creating a new flexible asset.

data

@{id=redacted(+1); type=flexible-assets; attributes=}

arpeake commented 6 years ago

It appears at least for me in PS 4 and PS 5 systems (I support none lower to confirm) but I too have the same issue. I simply broke down the one liner into basic logic and it works. Take note that its not refined, you should only have 1 match for this to not error out. More than one will error every time.

replace this

if($currentADFlexAssets.data.attributes.traits.${key_name_DomainName}) {
                    $fa_index = [array]::indexof($currentADFlexAssets.data.attributes.traits.${key_name_DomainName} ,$Domain)

                    if($fa_index -ne '-1') {
                        $api__flex_asset_id = $currentADFlexAssets.data[$fa_index].id
                    }
                }

with this

foreach($asset in $currentADFlexAssets)
                {
                    $dfn = $asset.data.attributes.traits | select -ExpandProperty domain-full-name

                    if(($dfn).ToLower() -eq ($Domain).ToLower())
                    {
                        $api__flex_asset_id = 0
                        $api__flex_asset_id = $asset.data.id
                        Write-Host "Asset Flex ID Found: " $api__flex_asset_id
                    }
                }

I also found various other issues with some of the ID checking or ORGs and what not. I am full auto-ing with the ITG Powershell commandline stuff with my APIKey in plaintext at the moment just kind of slopily throwing it down as I am new to ITG and these tools. Will work back around to mask the APIKey later but wanted to dive head first into this stuff.

Let me know if the check above works for you.

digitaltruss commented 6 years ago

That worked, thank you. I just had to replace "domain-full-name" with the name key specific to our Flexible Asset. And I have one client for which it is complaining about a null array while dealing with the global catalog servers. So far it is only occurring at that one client, so I may be on my own troubleshooting that!

I too am testing this out and hope to fully automate the scripts with Labtech. Aside from the security concern, how are you passing the API key in the script? The Add-ITGlueAPIKey command prompts for the key and hangs my script if I just place it after the command.

arpeake commented 6 years ago

Look at my fork, the -FullAuto directories are what I am running through my RMM. Just keep in mind that my API key is exposed in the ITGlueAPI\Internal\APIKey.ps1.

Its funny you mention 1 client, I too have the same damn thing happening with just 1 of my clients too. When I get some time later today I will look into that further.

arpeake commented 6 years ago

I found a couple issues with some of the code I gave you earlier as well as the potential problem with the failing client. The failing client has a DC that isnt in the clients "Configuration" so its not pulling the ID for it so it can properly tag it. Not sure yet how I want to handle this as in my case its an unmanaged device and 2 its decommissioned to my knowledge.

Im thinking if its not in the configuration of ITGlue then skip it, if its not already there its for a reason and if you add it later then re-run it will find it and run without issue.

digitaltruss commented 6 years ago

BINGO! We have a DC we do not manage in a remote office. Right in front of my face and I missed it. Hopefully that's our issue as well, and I will just add a dummy configuration.

The API key works perfectly as well, thank you.

arpeake commented 6 years ago

Very welcome, I have updated the ActiveDirectory.ps1 from my fork to include logic that skips missing configurations as well as properly adds new AD FlexAssets properly when they dont exist. In short I was missing some logic checking and if the records were not there they weren't being properly created because of an error in the script.

Had this before

if(($dfn).ToLower() -eq ($Domain).ToLower())
                        {
                            $api__flex_asset_id = 0
                            $api__flex_asset_id = $asset.data.id
                            Write-Host "Asset Flex ID Found: " $api__flex_asset_id
                        }

and wrapped a null/empty check around it.

if(![string]::IsNullOrEmpty($dfn))
                    {

                        if(($dfn).ToLower() -eq ($Domain).ToLower())
                        {
                            $api__flex_asset_id = 0
                            $api__flex_asset_id = $asset.data.id
                            Write-Host "Asset Flex ID Found: " $api__flex_asset_id
                        }
                    }
arpeake commented 6 years ago

I too am testing this out and hope to fully automate the scripts with Labtech. Aside from the security concern, how are you passing the API key in the script? The Add-ITGlueAPIKey command prompts for the key and hangs my script if I just place it after the command.

My APIKey is hardcoded in the ITGlueAPI\Internal\APIKey.ps1

APIKey.ps1

and a modified ITGlueAPI\Internal\ModuleSetting.ps1

ModuleSetting.ps1

When you type import-module ITGlueAPI is just runs a few basic things and interprets your APIkey. Essentially its just prepping the environment for use.

I deploy the package to the machine and copy it over to the C:\Program Files\WindowsPowerShell\Modules directory so its ready to run and then deploy my scripts to my working directory on the remote machines and then execute them. Was able to document everything relatively quickly.

CalebAlbers commented 6 years ago

Hi @digitaltruss and @arpeake ,

Thanks for the feedback. Indeed there were a few bugs you have found. @arpeake I appreciate the pull request. I'll review momentarily and merge.


As far as the API Key stuff goes, it is a bit of a tricky situation. IT Glue's API Keys are currently global, i.e. not organization specific. As such, the decision was made in the API wrapper to err on the side of caution with it. With that said, I am open to looking at alternative ways to deliver the API key.

There are methods of reversible encryption that could be used to transfer the API key into the secure storage method the module utilizes. Currently, the powershell module stores the API key as System.Security.SecureString, which is based off of the principal that stored the string (related directly to your Windows user account, for example). This has the side-effect of not allowing the module configuration (API key and base url) to be copied over to other systems.

I'd certainly be up for a discussion on alternative ways for storing API keys to make it easier to use with RMM platforms. Let me know if you have any ideas.

Thanks for the contributions!

arpeake commented 6 years ago

Caleb,

I noticed the string is not generic enough to transfer between machines, the encrypted config file is hashed per system, would be nice to be able to bundle a config with the powershell module for deployment.

The key wouldnt be in plain text and no more dangerous than leaving a config file behind.

On December 13, 2017 3:35:04 PM EST, Caleb Albers notifications@github.com wrote:

Hi @digitaltruss and @arpeake ,

Thanks for the feedback. Indeed there were a few bugs you have found. @arpeake I appreciate the pull request. I'll review momentarily and merge.


As far as the API Key stuff goes, it is a bit of a tricky situation. IT Glue's API Keys are currently global, i.e. not organization specific. As such, the decision was made in the API wrapper to err on the side of caution with it. With that said, I am open to looking at alternative ways to deliver the API key.

There are methods of reversible encryption that could be used to transfer the API key into the secure storage method the module utilizes. Currently, the powershell module stores the API key as System.Security.SecureString, which is based off of the principal that stored the string (related directly to your Windows user account, for example). This has the side-effect of not allowing the module configuration (API key and base url) to be copied over to other systems.

I'd certainly be up for a discussion on alternative ways for storing API keys to make it easier to use with RMM platforms. Let me know if you have any ideas.

Thanks for the contributions!

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/itglue/automation/issues/1#issuecomment-351514055

-- Sent from my Android device with K-9 Mail. Please excuse my brevity.

mrbiggles0007 commented 6 years ago

I have tried using all versions, made the modifications above and then tried the fully automated version and they all still create a new asset every single time.

I am currently getting the following error:


`Setting Flext Asset ID to empty to reset value
Checking current entries for match to existing domain name:  a.com
You cannot call a method on a null-valued expression.
At C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory.ps1:338 char:24
+                     if(($dfn).ToLower() -eq ($Domain).ToLower())
+                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull`