private void ProcessHashTable()
        {
            id = StartId;

            foreach (var table in HashTable)
            {
                var dict = table.ToDictionary();

                var bindingResult = GetStaticBindingResult(dict);

                var boundParameters  = GetInvokerBoundParameters(bindingResult);
                var parameterSetName = GetInvokerParameterSetName(bindingResult);

                if (!boundParameters.ContainsKey(nameof(StartId)))
                {
                    boundParameters[nameof(StartId)] = id;
                }

                ValidateMandatoryParameters(boundParameters, parameterSetName, dict);

                var instance = new NewSensorFactoryDefinition();

                var invoker = new PSCmdletInvoker(this, instance, parameterSetName, (c, b) =>
                {
                    object s;

                    //Not all parameter sets (e.g. Manual) require a sensor!
                    if (b.TryGetValue(nameof(Sensor), out s))
                    {
                        c.Sensor = (Sensor)s;
                    }
                });

                invoker.BindParameters(boundParameters);
                invoker.BeginProcessing(boundParameters);

                if (boundParameters.ContainsKey(nameof(Sensor)))
                {
                    foreach (var sensor in summarySensors)
                    {
                        boundParameters[nameof(Sensor)] = sensor;
                        invoker.ProcessRecord(boundParameters);
                    }
                }
                else
                {
                    invoker.ProcessRecord(boundParameters);
                }

                invoker.EndProcessing();

                id = instance.id;

                foreach (var item in invoker.Output)
                {
                    WriteObject(item);
                }
            }
        }
        public bool TryGetSensorTarget(NewSensor newSensorCmdlet, PrtgClient client, ref string propertyName, ref object propertyValue)
        {
            if (alternateSet != null)
            {
                var name = propertyName;

                var matchingParameter = alternateSet.Parameters.OfType <AlternateSensorTargetParameter>().FirstOrDefault(p => p.OriginalName == name);

                //If this is true, we are processing a sensor type that had an unbound parameter ("Services") that also had a replacement
                //sensor target parameter ("ServiceName"). Invoke Get-SensorTarget using the device the sensor will be created on,
                //the type of sensor we're creating and the value that was specified for the alternate target parameter (the specified ServiceName wildcards)
                if (matchingParameter != null)
                {
                    var invoker = new PSCmdletInvoker(
                        newSensorCmdlet,
                        new GetSensorTarget(),
                        new Lazy <string>(() => ParameterSet.Default),
                        (c, b) => c.Device = (Device)b[nameof(GetSensorTarget.Device)]
                        );

                    var boundParameters = new Dictionary <string, object>();
                    boundParameters[nameof(GetSensorTarget.Type)] = Type;
                    boundParameters[nameof(GetSensorTarget.Name)] = newSensorCmdlet.MyInvocation.BoundParameters[matchingParameter.Name];

                    invoker.BindParameters(boundParameters);
                    invoker.BeginProcessing(boundParameters);
                    invoker.ProcessRecord(newSensorCmdlet.MyInvocation.BoundParameters);

                    propertyName  = matchingParameter.Name;
                    propertyValue = invoker.Output;

                    return(true);
                }
            }

            return(false);
        }