FogApi.psm1
$PSModuleRoot = $PSScriptRoot $script:lib = "$PSModuleRoot\lib" $script:tools = "$PSModuleRoot\tools" function Add-FogHostMac { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $hostID, $macAddress, [switch]$primary, [switch]$ignoreMacOnClient, [switch]$ignoreMacForImaging ) process { if ($hostID.gettype().name -ne "Int32"){ try { $hostID = Get-FogHost -hostname $hostID } catch { Write-Error "Please provide a valid hostid or hostname" exit; } } if ($primary) { $primaryVal = '1' } else { $primaryVal = '0' } if ($ignoreMacForImaging) { $imageIgnoreVal = '1' } else { $imageIgnoreVal = '0' } if ($ignoreMacOnClient) { $clientIgnoreVal = '1' } else { $clientIgnoreVal = '0' } $newMac = @{ hostID = "$hostID" mac = "$macAddress" description = " " pending = '0' primary = $primaryVal clientIgnore = $clientIgnoreVal imageIgnore = $imageIgnoreVal } return New-FogObject -type object -coreObject macaddressassociation -jsonData ($newMac | ConvertTo-Json) } } function Approve-FogPendingMac { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( [object]$macObject ) process { $macObject.pending = '0'; $data = ($macObject | ConvertTo-Json); $result = Update-FogObject -type object -coreObject macaddressassociation -IDofObject $macObject.id -jsonData $data return $result; } } function Deny-FogPendingMac { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Remove-FogMac')] param ( [Parameter(Mandatory=$true)] $macObject ) process { return Remove-FogObject -type object -coreObject macaddressassociation -IDofObject $macObject.id; } } function Deploy-FogImage { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName='now')] [Alias('Push-FogImage','Send-FogImage')] param ( [Parameter(ParameterSetName='now')] [Parameter(ParameterSetName='schedule')] $hostId, [Parameter(ParameterSetName='schedule')] [datetime]$StartAtTime ) process { $fogHost = Get-FogHost -hostID $hostId; $currentImage = $fogHost.imageName; $fogImages = Get-FogImages; $fogImage = ($fogImages | Where-Object name -match $currentImage) "Creating Deploy Task for fog host of id $($hostID) named $($fogHost.name)" | Out-Host; "Will deploy the assigned image $($fogImage.name) - $($fogImage.id) which will install the os $($fogImage.osname)" | Out-host; if ($PSCmdlet.ParameterSetName -eq 'now') { "No Time was specified, queuing the task to start now" | out-host; $jsonData = "{`"taskTypeID`": `"1`", `"shutdown`":`"0`",`"other2`":`"0`",`"other4`":`"1`",`"isActive`":`"1`" }"; } else { "Start time of $($StartAtTime) specified, scheduling the task to start at that time" | out-host; $scheduleTime = Get-FogSecsSinceEpoch -scheduleDate $StartAtTime $runTime = get-date $StartAtTime -Format "yyyy-M-d HH:MM" $jsonData = @" { "name":"Deploy Task", "type":"S", "taskTypeID":"1", "runTime":"$runTime", "scheduleTime":"$scheduleTime", "isGroupTask":"0", "hostID":"$($hostId)", "shutdown":"0", "other2":"0", "other4":"1", "isActive":"1" } "@ } return New-FogObject -type objecttasktype -coreTaskObject host -jsonData $jsonData -IDofObject "$hostId"; } } function Get-FogActiveTasks { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () process { return Get-FogObject -type objectactivetasktype -coreActiveTaskObject task | Select-Object -ExpandProperty tasks } } function Get-FogAssociatedSnapins { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $hostId=((Get-FogHost).id) ) process { # $AllAssocs = (Invoke-FogApi -Method GET -uriPath snapinassociation).snapinassociations; $AllAssocs = (Get-FogObject -type object -coreObject snapinassociation).snapinassociations $snapins = New-Object System.Collections.Generic.List[object]; # $allSnapins = Get-FogSnapins; $AllAssocs | Where-Object hostID -eq $hostID | ForEach-Object { $snapinID = $_.snapinID; $snapin = Get-FogObject -type object -coreObject snapin -IDofObject $snapinID; # $snapins.add((Invoke-FogApi -uriPath "snapin\$snapinID")) $snapins.add($snapin) } return $snapins; } } function Get-FogGroupAssociations { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () process { $groupAssocs = (Get-FogObject -type object -coreObject groupassociation).groupassociations; return $groupAssocs; } } function Get-FogGroupByName { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $groupName ) begin { $groups = (Get-FogGroups) } process { $group = $groups | Where-Object name -match $groupName } end { return $group; } } function Get-FogGroups { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () process { $groups = (Get-FogObject -type object -coreobject group).groups; return $groups; } } function Get-FogHost { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName='searchTerm')] param ( [parameter(ParameterSetName='searchTerm')] [string]$uuid, [parameter(ParameterSetName='searchTerm')] [string]$hostName, [parameter(ParameterSetName='searchTerm')] [string]$macAddr, [parameter(ParameterSetName='byID',Mandatory=$true)] [string]$hostID, [parameter(ParameterSetName='serialNumber',Mandatory=$true)] [string]$serialNumber ) begin { [bool]$found = $false; Write-Verbose 'Checking for passed variables' if ($serialNumber) { $inventorys = (Get-FogObject -type object -coreObject inventory).inventorys $hostID = $inventorys | Where-Object { $_.sysserial -eq $serialNumber -OR $_.mbserial -eq $serialNumber -OR $_.caseserial -eq $serialNumber } | Select-Object -ExpandProperty HostID #find the inventory where the serial number matches one of the serial numbers in a hosts inventory and select the host id from that } elseif (!$uuid -and !$hostName -and !$macAddr -and !$hostID) { Write-Verbose 'no params given, getting current computer variables'; try { $compSys = Get-CimInstance -ClassName win32_computersystemproduct } catch { $compSys = (Get-WmiObject Win32_ComputerSystemProduct); } if ($compSys.UUID -notmatch "12345678-9012-3456-7890-abcdefabcdef" ) { $uuid = $compSys.UUID; } else { $uuid = ($compSys.Qualifiers | Where-Object Name -match 'UUID' | Select-Object -ExpandProperty Value); } # $macAddr = ((Get-NetAdapter | Select-Object MacAddress)[0].MacAddress).Replace('-',':'); $make = Get-CimInstance -classname win32_computersystem | Select-Object -ExpandProperty manufacturer if (($Make) -notmatch "vmware" ) { $macAddr = ( Get-NetAdapter | Where-Object { $_.Status -eq 'up' -And $_.Name -notmatch 'VMware' } | Select-Object -first 1 | Select-Object -expand MacAddress ).Replace("-",":"); } else { $macAddr = ( Get-NetAdapter | Where-Object { $_.Status -eq 'up' } | Select-Object -first 1 | Select-Object -expand MacAddress ).Replace("-",":"); } $hostName = $(hostname); } else { if ($hostID) { Write-Verbose "getting host from ID $hostID directly..." } } Write-Verbose 'getting all hosts to search...'; Write-Verbose "search terms: uuid is $uuid, macAddr is $macAddr, hostname is $hostName"; } process { Write-Verbose 'finding host in hosts'; [bool]$found = $false; if ($hostID) { $hostObj = get-fogobject -type object -coreObject host -IDofObject "$hostID"; if ($null -ne $hostObj) { $found = $true; } } else { $hosts = (Get-FogHosts) $hostObj = $hosts | Where-Object { ($uuid -ne "" -AND $_.inventory.sysuuid -eq $uuid) -OR ` ($hostName -ne "" -AND $_.name -eq $hostName) -OR ` ($macAddr -ne "" -AND $_.macs -contains $macAddr); if ($uuid -ne "" -AND $_.inventory.sysuuid -eq $uuid) { $found = $true; Write-Verbose "$($_.inventory.sysuuid) matches the uuid $uuid`! host found is $found"; } if ($macAddr -ne "" -AND $_.macs -contains $macAddr) { Write-Verbose "$($_.macs) matches the macaddress $macAddr`! host found"; $found = $true; } if ($hostName -ne "" -AND $_.name -eq $hostName) { Write-Verbose "$($_.name) matches the hostname $hostName`! host found"; $found = $true; } } } } end { if ($found){ if ($hostObj.count -gt 1) { if ($hostName) { $hostObjByName = $hostObj | Where-Object name -eq $hostName; if ($null -ne $hostObjByName) { $hostObj = $hostObjByName } else { "Multiple hosts found and none of them match given hostname! Review hosts in return object and select just one if needed" | Out-Host; } } else { "Multiple hosts found! Review hosts in return object and select just one if needed" | Out-Host; } } return $hostObj; } return $found; #return false if host not found } } function Get-FogHostGroup { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Get-FogGroup')] param ( [int]$hostId ) begin { [bool]$found = $false; Write-Verbose 'Getting all fog group associations...'; # $groupAssocs = (Invoke-FogApi -uriPath groupassociation).groupassociations; $groupAssocs = Get-FogGroupAssociations; Write-Verbose 'Getting all fog groups...'; $groups = Get-FogGroups; } process { $hostGroups = $groupAssocs | Where-Object hostID -eq $hostId; $found = $true; $group = $groups | Where-Object id -eq $hostGroups.groupID; $group = $hostGroups; } end { if($found){ return $group; } return $found; } } function Get-FogHostMacs { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Get-MacsForHost')] param ( $hostObject = (Get-FogHost) ) begin { $macs = Get-FogMacAddresses; } process { $hostMacs = $macs | Where-Object hostID -eq $hostObject.id } end { return $hostMacs; } } function Get-FogHosts { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () begin { Write-Verbose "getting fog hosts" } process { $hosts = Get-FogObject -type Object -CoreObject host | Select-Object -ExpandProperty hosts } end { return $hosts; } } function Get-FogImages { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( ) process { return (Get-FogObject -type object -coreObject image | select-object -ExpandProperty images); } } function Get-FogInventory { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $hostObj = (Get-FogHost), [switch]$fromFog ) process { if ($IsLinux -OR $fromFog) { if ($IsLinux) { "Not yet implemented for getting the host inventory from linux inline, returning the hosts currently set inventory object" | out-host; } return $hostObj.inventory; } else { $comp = Get-CimInstance -ClassName Win32_ComputerSystem; $compSys = Get-CimInstance -ClassName Win32_ComputerSystemProduct; $cpu = Get-CimInstance -ClassName Win32_processor; $bios = Get-CimInstance -ClassName Win32_Bios; $hdd = Get-CimInstance -ClassName Win32_DiskDrive | Where-Object DeviceID -match '0'; #get just drive 0 in case of multiple drives $baseBoard = Get-CimInstance -ClassName Win32_BaseBoard; $case = Get-CimInstance -ClassName Win32_SystemEnclosure; $info = Get-ComputerInfo; } $hostObj.inventory.hostID = $hostObj.id; # $hostObj.inventory.primaryUser = # $hostObj.inventory.other1 = # $hostObj.inventory.other2 = $hostObj.inventory.createdTime = $((get-date -format u).replace('Z','')); # $hostObj.inventory.deleteDate = '0000-00-00 00:00:00' $hostObj.inventory.sysman = $compSys.Vendor; #manufacturer $hostObj.inventory.sysproduct = $compSys.Name; #model $hostObj.inventory.sysversion = $compSys.Version; $hostObj.inventory.sysserial = $compSys.IdentifyingNumber; if ($compSys.UUID -notmatch "12345678-9012-3456-7890-abcdefabcdef" ) { $hostObj.inventory.sysuuid = $compSys.UUID; } else { $hostObj.inventory.sysuuid = ($compSys.Qualifiers | Where-Object Name -match 'UUID' | Select-Object -ExpandProperty Value); } $hostObj.inventory.systype = $case.chassistype; #device form factor found chassistype member of $case but it references a list that hasn't been updated anywhere I can find. i.e. returns 35 for a minipc but documented list only goes to 24 $hostObj.inventory.biosversion = $bios.name; $hostObj.inventory.biosvendor = $bios.Manufacturer; $hostObj.inventory.biosdate = $(get-date $info.BiosReleaseDate -Format d); $hostObj.inventory.mbman = $baseBoard.Manufacturer; $hostObj.inventory.mbproductname = $baseBoard.Product; $hostObj.inventory.mbversion = $baseBoard.Version; $hostObj.inventory.mbserial = $baseBoard.SerialNumber; $hostObj.inventory.mbasset = $baseBoard.Tag; $hostObj.inventory.cpuman = $cpu.Manufacturer; $hostObj.inventory.cpuversion = $cpu.Name; $hostObj.inventory.cpucurrent = "Current Speed: $($cpu.currentClockSpeed) MHz"; $hostObj.inventory.cpumax = "Max Speed $($cpu.MaxClockSpeed) MHz"; $hostObj.inventory.mem = "MemTotal: $($comp.TotalPhysicalMemory) kB"; $hostObj.inventory.hdmodel = $hdd.Model; $hostObj.inventory.hdserial = $hdd.SerialNumber; $hostObj.inventory.hdfirmware = $hdd.FirmareRevision; $hostObj.inventory.caseman = $case.Manufacturer; $hostObj.inventory.casever = $case.Version; $hostObj.inventory.caseserial = $case.SerialNumber; $hostObj.inventory.caseasset = $case.SMBIOSAssetTag; $hostObj.inventory.memory = "$([MATH]::Round($(($comp.TotalPhysicalMemory) / 1GB),2)) GiB"; $jsonData = $hostObj.inventory | ConvertTo-Json; return $jsonData; } } function Get-FogLog { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( [switch]$static ) begin { $fogLog = 'C:\fog.log'; } process { if (!$static) { "Starting dynamic fog log in new window, Hit Ctrl+C on new window or close it to exit dynamic fog log" | Out-Host; Start-Process Powershell.exe -ArgumentList "-Command `"Get-Content $fogLog -Wait`""; } else { Get-Content $fogLog; } } end { return; } } function Get-FogMacAddresses { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Get-FogMacs')] param () process { $macs = Get-FogObject -type object -coreObject macaddressassociation | select-object -ExpandProperty macaddressassociations return $macs; } } function Get-FogModules { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () process { $modules = (Get-FogObject -type object -coreObject module).modules return $modules; } } function Get-FogObject { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( # The type of object being requested [Parameter(Position=0)] [ValidateSet("objectactivetasktype","object","search")] [string]$type, # The json data for the body of the request [Parameter(Position=2)] [Object]$jsonData, # The id of the object to get [Parameter(Position=3)] [string]$IDofObject ) DynamicParam { $paramDict = Set-DynamicParams $type; return $paramDict;} begin { $paramDict | ForEach-Object { New-Variable -Name $_.Keys -Value $($_.Values.Value);} Write-Verbose "Building uri and api call for $($paramDict.keys) $($paramDict.values.value)"; switch ($type) { objectactivetasktype { $uri = "$coreActiveTaskObject/current"; } object { if ($null -eq $IDofObject -OR $IDofObject -eq "") { $uri = "$coreObject"; } else { $uri = "$coreObject/$IDofObject"; } } search { $uri = "$type/$stringToSearch"; } } Write-Verbose "uri for get is $uri"; $apiInvoke = @{ uriPath=$uri; Method="GET"; jsonData=$jsonData; } if ($null -eq $apiInvoke.jsonData -OR $apiInvoke.jsonData -eq "") { $apiInvoke.Remove("jsonData"); } } process { $result = Invoke-FogApi @apiInvoke; } end { return $result; } } function Get-FogSecsSinceEpoch { # .ExternalHelp FogApi-help.xml param ( $scheduleDate = (Get-Date) ) process { $EpochDiff = New-TimeSpan "01 January 1970 00:00:00" $($scheduleDate) $EpochSecs = [INT] $EpochDiff.TotalSeconds - [timezone]::CurrentTimeZone.GetUtcOffset($(get-date)).totalseconds return $EpochSecs } } function Get-FogServerSettings { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () begin { Write-Verbose "Pulling settings from settings file" $settingsFile = "$home/APPDATA/Roaming/FogApi/api-settings.json" if (!(Test-path $settingsFile)) { Write-Warning "Api Settings file not yet created, creating default version now!" if (!(Test-Path "$home/APPDATA")) { mkdir "$home/APPDATA" } if (!(Test-Path "$home/APPDATA/Roaming")) { mkdir "$home/APPDATA/Roaming" } if (!(Test-Path "$home/APPDATA/Roaming/FogApi")) { mkdir "$home/APPDATA/Roaming/FogApi"; } Copy-Item -path "$script:lib\settings.json" -Destination $settingsFile -Force } } process { $serverSettings = (Get-Content $settingsFile | ConvertFrom-Json); } end { return $serverSettings; } } function Get-FogSnapins { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param () process { return (Get-FogObject -type object -coreObject snapin | Select-Object -Expand snapins) # return (Invoke-FogApi -Method GET -uriPath snapin).snapins; } } function Get-LastImageTime { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName="bySN")] param ( [parameter(ParameterSetName='bySN')] $serialNumber, #scan the barcode input into powershell [parameter(ParameterSetName='byHostId')] $hostId, [parameter(ParameterSetName='byHost')] $fogHost, [parameter(ParameterSetName='byHost')] [switch]$currentHost ) process { switch ($PSCmdlet.ParameterSetName) { bySN { Write-Verbose "Getting host by serial number" if (!$serialNumber) { $serialNumber = (Read-Host -Prompt "Scan Serial Number barcode") } $fogHost = Get-FogHost -serialNumber $serialNumber; $HostID = $fogHost.id; } byHostID { Write-Verbose "Getting host by id" $fogHost = Get-FogHost -hostID $hostId; } byHost { if (!$fogHost) { Write-Verbose "getting host of current machine" $fogHost = (Get-FogHost) } $HostID = $fogHost.id } } $imageLog = (get-fogobject -type object -coreObject imaginglog).imagingLogs # get the image history log $hostLogs = $imageLog | where-object hostid -eq $HostID # get the image history logs for the given host if (!$hostLogs) { Write-Warning "No imaging logs found for host $($fogHost.name)!" return $null; } else { $hostLog = $hostLogs[-1] # select the last/most recent log #return a string of the information about the serial number if ($serialNumber) { "Serial number $serialNumber belongs to host $($fogHost.name), it was last imaged at $($hostLog.start) with the image $($hostLog.image)" | Out-Host } else { "hostname is $($fogHost.name), it was last imaged at $($hostLog.start) with the image $($hostLog.image)" | Out-Host } return $hostLog; } } } function Get-PendingMacsForHost { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $hostID ) process { if ($hostID.gettype().name -ne "Int32"){ try { $hostID = (Get-FogHost -hostname $hostID).id } catch { Write-Error "Please provide a valid hostid or hostname" exit; } } $hostMacs = Get-MacsForHost -host ((Get-FogHost -hostID $hostID)) $pendingMacs = $hostMacs | Where-Object pending -eq '1'; return $pendingMacs; } } function Install-FogService { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $fogServer = ((Get-FogServerSettings).fogServer) ) begin { $fileUrl = "http://$fogServer/fog/client/download.php?newclient"; $fileUrl2 = "http://$fogServer/fog/client/download.php?smartinstaller"; Write-Host "Making temp download dir"; mkdir C:\fogtemp; Write-Host "downloading installer"; Invoke-WebRequest -URI $fileUrl -UseBasicParsing -OutFile 'C:\fogtemp\fog.msi'; Invoke-WebRequest -URI $fileUrl2 -UseBasicParsing -OutFile 'C:\fogtemp\fog.exe'; } process { Write-Host "installing fog service"; try { Start-Process -FilePath msiexec -ArgumentList @('/i','C:\fogtemp\fog,msi','/quiet','/qn','/norestart') -NoNewWindow -Wait; } catch { if ($null -eq (Get-Service FogService -EA 0)) { & "C:\fogTemp\fog.exe"; Write-Host "Waiting 10 seconds then sending 10 enter keys" Start-Sleep 10 $wshell = New-Object -ComObject wscript.shell; $wshell.AppActivate('Fog Service Setup') $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Space}") $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") Write-Host "waiting 30 seconds for service to install" Start-Sleep 30 Write-host "sending more enter keys" $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") $wshell.SendKeys("{Enter}") } } } end { Write-Host "removing download file and temp folder"; Remove-Item -Force -Recurse C:\fogtemp; Write-Host "Starting fogservice"; if ($null -ne (Get-Service FogService)) { Start-Service FOGService; } return; } } function Invoke-FogApi { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( [string]$uriPath, [string]$Method="GET", [string]$jsonData ) begin { Write-Verbose "Pulling settings from settings file" # Set-FogServerSettings; $serverSettings = Get-FogServerSettings; [string]$fogApiToken = $serverSettings.fogApiToken; [string]$fogUserToken = $serverSettings.fogUserToken; [string]$fogServer = $serverSettings.fogServer; $baseUri = "http://$fogServer/fog"; # Create headers Write-Verbose "Building Headers..."; $headers = @{}; $headers.Add('fog-api-token', $fogApiToken); $headers.Add('fog-user-token', $fogUserToken); # Set the Uri Write-Verbose "Building api call URI..."; $uri = "$baseUri/$uriPath"; $uri = $uri.Replace('//','/') $uri = $uri.Replace('http:/','http://') $apiCall = @{ Uri = $uri; Method = $Method; Headers = $headers; Body = $jsonData; ContentType = "application/json" } if ($null -eq $apiCall.Body -OR $apiCall.Body -eq "") { Write-Verbose "removing body from call as it is null" $apiCall.Remove("Body"); } } process { Write-Verbose "$Method`ing $jsonData to/from $uri"; try { $result = Invoke-RestMethod @apiCall -ea Stop; } catch { $result = Invoke-WebRequest @apiCall; } } end { Write-Verbose "finished api call"; return $result; } } function New-FogHost { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName='default')] [Alias('Add-FogHost')] param ( [Parameter(Mandatory=$true,ParameterSetName='default')] [string]$name, [Parameter(Mandatory=$true,ParameterSetName='default')] [string[]]$macs, [Parameter(ParameterSetName='default')] [string[]]$modules = ((Get-FogModules | Where-Object isDefault -eq '1') | Select-Object -ExpandProperty id), [Parameter(Mandatory=$true,ParameterSetName='custom')] [object]$customHost ) begin { if ($PSCmdlet.ParameterSetName -eq 'default') { if ($name -match " ") { Write-Warning "name $name includes whitespace, replacing whitespace with - if not at end of string"; $name = $name.TrimEnd(); $name = $name.Replace(" ","-"); "new name is $name" | Out-Host; } $hostObject = @{ name = $name; macs = $macs; modules = $modules; } } else { $hostObject = $customHost; "Custom host is specified, no validation being performed, object properties are $($hostObject | Out-String)" } $hostJson = $hostObject | ConvertTo-Json; } process { if ($PSCmdlet.ParameterSetName -eq 'default') { try { Write-Verbose "Checking for existing name" $hostNameCheck = Get-FogHost -hostName $name; if ($hostNameCheck) { Write-Warning "host with name $name already exists, returning existing host object"; return $hostNameCheck; } $hostMacCheck = New-Object System.Collections.Generic.list[object]; $macs | ForEach-Object { "Checking for existings host with mac $($_)" | Out-Host; $hostMacCheckItem = (Get-FogHost -macAddr $_); if ($hostMacCheckItem) { Write-Warning "mac address $($_) already exists on host $($hostMacCheckItem.name)"; $hostMacCheck.add(($hostMacCheckItem)); } } if ($hostMacCheck.count -gt 0) { Write-Warning "some macs already exist on hosts, returning list of matching host objects"; return $hostMacCheck; } } catch { Write-Warning "Error during input validation, attempting to create new host" } } "Creating new Host $hostObject" | Out-Host; $newHost = New-FogObject -type object -coreObject host -jsonData $hostJson } end { if ($null -ne $newHost) { return $newHost; } } } function New-FogObject { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Add-FogObject')] param ( # The type of object being requested [Parameter(Position=0)] [ValidateSet("objecttasktype","object")] [string] $type, # The json data for the body of the request [Parameter(Position=2)] [Object]$jsonData, # The id of the object when creating a new task [Parameter(Position=3)] [string]$IDofObject ) DynamicParam { $paramDict = Set-DynamicParams $type; return $paramDict;} begin { $paramDict | % { New-Variable -Name $_.Keys -Value $($_.Values.Value);} Write-Verbose "Building uri and api call"; switch ($type) { objecttasktype { $uri = "$CoreTaskObject/$IDofObject/task"; } object { $uri = "$CoreObject/create"; } } $apiInvoke = @{ uriPath=$uri; Method="POST"; jsonData=$jsonData; } } process { $result = Invoke-FogApi @apiInvoke; } end { return $result; } } function Receive-FogImage { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName='now')] [Alias('Save-FogImage','Invoke-FogImageCapture')] param ( [Parameter(ParameterSetName='now')] [Parameter(ParameterSetName='schedule')] $hostId, [Parameter(ParameterSetName='schedule')] [datetime]$StartAtTime ) process { $fogHost = Get-FogHost -hostID $hostId; $currentImage = $fogHost.imageName; $fogImages = Get-FogImages; $fogImage = ($fogImages | Where-Object name -match $currentImage) "Creating Capture Task for fog host of id $($hostID) named $($fogHost.name)" | Out-Host; "Will capture the assigned image $($fogImage.name) - $($fogImage.id) which will capture the os $($fogImage.osname)" | Out-host; if ($PSCmdlet.ParameterSetName -eq 'now') { "No Time was specified, queuing the task to start now" | out-host; $jsonData = "{`"taskTypeID`": `"2`" }"; } else { "Start time of $($StartAtTime) specified, scheduling the task to start at that time" | out-host; $scheduleTime = Get-FogSecsSinceEpoch -scheduleDate $StartAtTime $runTime = get-date $StartAtTime -Format "yyyy-M-d HH:MM" $jsonData = @" { "name":"Capture Task", "type":"S", "taskTypeID":"2", "runTime":"$runTime", "scheduleTime":"$scheduleTime", "isGroupTask":"0", "hostID":"$($hostId)", "shutdown":"0", "other2":"0", "other4":"1", "isActive":"1" } "@ } return New-FogObject -type objecttasktype -coreTaskObject host -jsonData $jsonData -IDofObject "$hostId"; } } function Remove-FogObject { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( # The type of object being requested [Parameter(Position=0)] [ValidateSet("objecttasktype","objectactivetasktype","object")] [string]$type, # The json data for the body of the request [Parameter(Position=2)] [Object]$jsonData, # The id of the object to remove [Parameter(Position=3)] [string]$IDofObject ) DynamicParam { $paramDict = Set-DynamicParams $type; return $paramDict;} begin { $paramDict | ForEach-Object { New-Variable -Name $_.Keys -Value $($_.Values.Value);} Write-Verbose "Building uri and api call"; switch ($type) { objecttasktype { $uri = "$CoreTaskObject/$IDofObject/cancel"; } object { $uri = "$CoreObject/$IDofObject/delete"; } objectactivetasktype { $uri = "$CoreActiveTaskObject/cancel" } } $apiInvoke = @{ uriPath=$uri; Method="DELETE"; jsonData=$jsonData; } if ($apiInvoke.jsonData -eq $null -OR $apiInvoke.jsonData -eq "") { $apiInvoke.Remove("jsonData"); } } process { $result = Invoke-FogApi @apiInvoke; } end { return $result; } } function Remove-UsbMac { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( [string[]]$usbMacs, [string]$hostname = "$(hostname)", $macId ) begin { if ($null -eq $usbMacs) { Write-Error "no macs to remove given"; exit; } Write-Verbose "remove usb ethernet adapter from host $hostname on fog server $fogServer ...."; # get the host id by getting all hosts and searching the hosts array of the returned json for the item that has a name matching the current hostname and get the host id of that item $hostObj = Get-FogHost -hostName $hostname; $hostId = $hostObj.id; # $hostId = ( (Invoke-FogApi -fogServer $fogServer -fogApiToken $fogApiToken -fogUserToken $fogUserToken).hosts | Where-Object name -match "$hostname" ).id; # With the host id get mac associations that match that host id. try { $macs = Get-FogObject -type object -coreObject macaddressassociation | select-object -ExpandProperty macaddressassociations | Where-Object hostID -match $hostID } catch { $macs = (Invoke-FogApi -uriPath "macaddressassociation").macaddressassociations | Where-Object hostID -match "$hostId"; } # Copy the return fixedsize json array collection to a new powershell list variable for add and remove functions $macList = New-Object System.Collections.Generic.List[System.Object]; try { $macs.ForEach({ $macList.add($_.mac); }); } catch { $macs | ForEach-Object{ $macList.add($_.mac); } } } process { # Check if any usbmacs are contained in the host's macs $usbMacs | ForEach-Object { #loop through list of usbMacs if ( $macList.contains($_) ) { # check if the usbMac is contained in the mac list of the host # Remove from the list so a new primary can be picked if needed $macList.Remove($_); Write-Verbose "$_ is a $usbMac connected to $hostname, checking if it is the primary..."; $macItem = ($macs | Where-Object mac -eq $_ ); if ( $macItem.primary -eq '1' ) { Write-Verbose "It is primary, let's fix that and set $($macList[0]) to primary"; $macItem.primary = '0'; try { Update-FogObject -type object -coreObject macaddressassociation -IDofObject $macItem.id -jsonData ($macItem | ConvertToJson) } catch { $removePrimaryAttribute = @{ uriPath = "macaddressassociation/$($macItem.id)/edit"; Method = 'Put'; jsonData = ($macItem | ConvertTo-Json); } Invoke-FogApi @removePrimaryAttribute; } Write-Verbose "Primary attribute removed, setting new primary..."; $newPrimary = ($macs | Where-Object mac -eq $macList[0] ); if ($null -eq $newPrimary) { Write-Verbose "host only has usbmacs, adding first non usbmac adapter"; $physicalMacs = (get-netadapter | select-object -expand macaddress).replace("-",":") $physicalMacs = $physicalMacs | Where-Object {$_ -NotIn $usbMacs}; Add-FogHostMac -hostID $hostID -macAddress $physicalMacs[0] -primary; } else { $newPrimary.primary = '1'; $newPrimary.pending = '0'; Update-FogObject -type object -coreObject macaddressassociation -IDofObject $newPrimary.id -jsonData ($newPrimary | ConvertTo-Json) } } Write-Verbose "Remove the usb ethernet mac association"; try { $result += Remove-FogObject -type object -coreObject macaddressassociation -IDofObject $macItem.id; } catch { $removeMacAssoc = @{ uriPath = "macaddressassociation/$($macItem.id)/delete"; Method = 'Delete'; } $result += Invoke-FogApi @removeMacAssoc; } Write-Verbose "Usb macs $usbMacs have been removed from $hostname on the $fogServer"; } } } end { if ($null -eq $result) { $result = "no usb adapters found"; #replace string if found } return $result; } } function Reset-HostEncryption { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $fogHost = (Get-FogHost), [switch]$restartSvc ) process { $fogHost.pub_key = ""; $fogHost.sec_tok = ""; $fogHost.sec_time = "0000-00-00 00:00:00"; $jsonData = $fogHost | Select-Object id,pub_key,sec_tok,sec-time | ConvertTo-Json; $result = Update-FogObject -type object -coreObject host -IDofObject $fogHost.id -jsonData $jsonData; if ($restartSvc) { Restart-Service fogservice -force; } return $result; } } function Set-FogInventory { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $hostObj = (Get-FogHost), $jsonData = (Get-FogInventory -hostObj $hostObj) ) begin { $inventoryApi = @{ jsonData = $jsonData; Method = 'Post'; uriPath = "inventory/new"; } } process { Invoke-FogApi @inventoryApi -verbose; } end { return; } } function Set-FogServerSettings { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName='default')] param ( [parameter(ParameterSetName='default')] [string]$fogApiToken, [parameter(ParameterSetName='default')] [string]$fogUserToken, [parameter(ParameterSetName='default')] [string]$fogServer, [parameter(ParameterSetName='prompt')] [switch]$interactive ) begin { $settingsFile = "$home/APPDATA/Roaming/FogApi/api-settings.json" # if (!(Test-path $settingsFile)) { # if (!(Test-Path "$home/APPDATA")) { # mkdir "$home/APPDATA" # } # if (!(Test-Path "$home/APPDATA/Roaming")) { # mkdir "$home/APPDATA/Roaming" # } # if (!(Test-Path "$home/APPDATA/Roaming/FogApi")) { # mkdir "$home/APPDATA/Roaming/FogApi"; # } # Copy-Item "$script:lib\settings.json" $settingsFile -Force # } $ServerSettings = Get-FogServerSettings; Write-Verbose "Current/old Settings are $($ServerSettings)"; $helpTxt = @{ fogApiToken = "fog API token found at https://fog-server/fog/management/index.php?node=about&sub=settings under API System"; fogUserToken = "your fog user api token found in the user settings https://fog-server/fog/management/index.php?node=user&sub=list select your api enabled used and view the api tab"; fogServer = "your fog server hostname or ip address to be used for created the url used in api calls default is fog-server or fogServer"; } } process { if($interactive) { ($serverSettings.psobject.properties | Where-Object name -eq Keys).Value | ForEach-Object { $var = (Get-Variable -Name $_); if ($null -eq $var.Value -OR $var.Value -eq "") { Set-Variable -name $var.Name -Value (Read-Host -Prompt "help message: $($helpTxt.($_))`nEnter the $($var.name)"); } } } elseif( #if all params are passed and not null create new settings object !([string]::IsNullOrEmpty($fogApiToken)) -AND !([string]::IsNullOrEmpty($fogUserToken)) -AND !([string]::IsNullOrEmpty($fogServer)) ) { $serverSettings = @{ fogApiToken = $fogApiToken; fogUserToken = $fogUserToken; fogServer = $fogServer; } } else { #check for some setting being passed but not all and set them individually if (!([string]::IsNullOrEmpty($fogApiToken))) { $ServerSettings.fogApiToken = $fogApiToken; } if (!([string]::IsNullOrEmpty($fogUserToken))) { $ServerSettings.fogUserToken = $fogUserToken; } if (!([string]::IsNullOrEmpty($fogServer))) { $ServerSettings.fogServer = $fogServer; } $serverSettings | ConvertTo-Json | Out-File -FilePath $settingsFile -Encoding oem -Force; } # If given paras are null just pulls from settings file # If they are not null sets the object to passed value Write-Verbose "making sure all settings are set"; if ( $ServerSettings.fogApiToken -eq $helpTxt.fogApiToken -OR $ServerSettings.fogUserToken -eq $helpTxt.fogUserToken -OR $ServerSettings.fogServer -eq $helpTxt.fogServer -or ([string]::IsNullOrEmpty($ServerSettings.fogApiToken)) -OR ([string]::IsNullOrEmpty($ServerSettings.fogUserToken)) -OR ([string]::IsNullOrEmpty($ServerSettings.fogServer)) ) { Write-Host -BackgroundColor Yellow -ForegroundColor Red -Object "a fog setting is either null or still set to its default help text, opening the settings file for you to set the settings" Write-Host -BackgroundColor Yellow -ForegroundColor Red -Object "This script will close after opening settings in notepad, please re-run command after updating settings file"; if ($isLinux) { $editor = 'nano'; } elseif($IsMacOS) { $editor = 'TextEdit'; } else { $editor = 'notepad.exe'; } Start-Process -FilePath $editor -ArgumentList "$SettingsFile" -NoNewWindow -PassThru; return; } } end { Write-Verbose "Writing new Settings"; $serverSettings | ConvertTo-Json | Out-File -FilePath $settingsFile -Encoding oem -Force; return (Get-Content $settingsFile | ConvertFrom-Json); } } function Set-FogSnapins { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Add-FogSnapins')] param ( $hostid = ((Get-FogHost).id), $pkgList ) process { Write-Verbose "Association snapins from package list with host"; $snapins = Get-FogSnapins; # $urlPath = "snapinassociation/create" $curSnapins = Get-FogAssociatedSnapins -hostId $hostid; $result = New-Object System.Collections.Generic.List[Object]; if ($null -ne $pkgList) { $pkgList | ForEach-Object { $json = @{ hostID = $hostid snapinID = (($snapins | Where-Object name -match "$($_)").id); }; Write-Verbose "$_ is pkg snapin id found is $($json.snapinID)"; if (($null -ne $json.SnapinID) -AND ($json.SnapinID -notin $curSnapins.id)) { $json = $json | ConvertTo-Json; $result.add((New-FogObject -type object -coreObject snapinassociation -jsonData $json)); } elseif ($json.SnapinID -in $curSnapins.id) { Write-Warning "$_ snapin of id $($json.SnapinID) is already associated with this host"; } else { Write-Warning "no snapin ID found for $_ pkg"; } # Invoke-FogApi -Method POST -uriPath $urlPath -jsonData $json; } } return $result; } } function Start-FogSnapin { # .ExternalHelp FogApi-help.xml [CmdletBinding(DefaultParameterSetName='byId')] param ( [parameter(ParameterSetName='byId')] [parameter(ParameterSetName='byName')] $hostID, [parameter(ParameterSetName='byName')] $snapinname, [parameter(ParameterSetName='byId')] $snapinId ) process { $snapins = Get-FogSnapins; if ($PSCmdlet.ParameterSetName -eq 'byName') { $snapin = $snapins | Where-Object name -eq $snapinname; $snapinId = $snapin.id } else { $snapin = $snapins | Where-Object id -eq $snapinId; $snapinname = $snapin.name } if ($null -eq $snapinId) { Write-Warning "No snapinid was found for the snapin $snapinName! not running any actions" return $null } else { $json = (@{ "taskTypeID"='13'; "deploySnapins"="$snapinId"; } | ConvertTo-Json); $fogHost = Get-Foghost -hostID $hostID; "Deploying the snapin $snapinname to the host $($fogHost.name)" | out-host; New-FogObject -type objecttasktype -coreTaskObject host -jsonData $json -IDofObject "$hostID"; } } } function Start-FogSnapins { # .ExternalHelp FogApi-help.xml [CmdletBinding()] param ( $hostid = ((Get-FogHost).id), $taskTypeid = '12' ) begin { Write-Verbose "Stopping any queued snapin tasks"; try { $tasks = Get-FogActiveTasks; } catch { $tasks = (Invoke-FogApi -Method GET -uriPath "task/active").tasks; } $tasks = $tasks | Where-Object { $_.type.id -match $taskTypeid} #filter task list to all snapins task. $taskID = (($tasks | Where-Object hostID -match $hostid).id); if ($null -ne $taskID) { #if active snapin tasks are found for the host cancel them, otherwise do nothing to tasks Write-Verbose "Found $($taskID.count) tasks deleting them now"; $taskID | ForEach-Object{ try { Remove-FogObject -type objecttasktype -coreTaskObject task -IDofObject $_; } catch { Invoke-FogApi -Method DELETE -uriPath "task/$_/cancel"; } } } # $snapAssocs = Invoke-FogApi -uriPath snapinassociation -Method Get; # $snaps = $snapAssocs.snapinassociations | ? hostid -eq $hostid; } process { Write-Verbose "starting all snapin task for host"; $json = (@{ "taskTypeID"=$taskTypeid; "deploySnapins"=-1; } | ConvertTo-Json); New-FogObject -type objecttasktype -coreTaskObject host -jsonData $json -IDofObject $hostid; } end { Write-Verbose "Snapin tasks have been queued on the server"; return; } } function Update-FogObject { # .ExternalHelp FogApi-help.xml [CmdletBinding()] [Alias('Set-FogObject')] param ( # The type of object being requested [Parameter(Position=0)] [ValidateSet("object")] [string]$type, # The json data for the body of the request [Parameter(Position=2)] [Object]$jsonData, # The id of the object to remove [Parameter(Position=3)] [string]$IDofObject, [Parameter(Position=4)] [string]$uri ) DynamicParam { $paramDict = Set-DynamicParams $type; return $paramDict; } begin { $paramDict | ForEach-Object { New-Variable -Name $_.Keys -Value $($_.Values.Value);} Write-Verbose "Building uri and api call"; if([string]::IsNullOrEmpty($uri)) { $uri = "$CoreObject/$IDofObject/edit"; } $apiInvoke = @{ uriPath=$uri; Method="PUT"; jsonData=$jsonData; } } process { $result = Invoke-FogApi @apiInvoke; } end { return $result; } } function Get-DynmicParam { <# .SYNOPSIS Gets the dynamic parameter for the main functions .DESCRIPTION Dynamically sets the correct tab completeable validate set for the coreobject, coretaskobject, coreactivetaskobject, or string to search .PARAMETER paramName the name of the parameter being dynamically set within the validate set .PARAMETER position the position to put the dynamic parameter in #> [CmdletBinding()] param ( [Parameter(Position=0)] [ValidateSet('coreObject','coreTaskObject','coreActiveTaskObject','stringToSearch')] [string]$paramName, $position=1 ) begin { #initilzie objects $attributes = New-Object Parameter; #System.Management.Automation.ParameterAttribute; $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] # $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary # Set attributes $attributes.Position = $position; $attributes.Mandatory = $true; $attributeCollection.Add($attributes) $coreObjects = @( "clientupdater", "dircleaner", "greenfog", "group", "groupassociation", "history", "hookevent", "host", "hostautologout", "hostscreensetting", "image", "imageassociation", "imagepartitiontype", "imagetype", "imaginglog", "inventory", "ipxe", "keysequence", "macaddressassociation", "module", "moduleassociation", "multicastsession", "multicastsessionsassociation", "nodefailure", "notifyevent", "os", "oui", "plugin", "powermanagement", "printer", "printerassociation", "pxemenuoptions", "scheduledtask", "service", "snapin", "snapinassociation", "snapingroupassociation", "snapinjob", "snapintask", "storagegroup", "storagenode", "task", "tasklog", "taskstate", "tasktype", "usercleanup", "usertracking", "virus" ); $coreTaskObjects = @("group", "host", "multicastsession", "snapinjob", "snapintask", "task"); $coreActiveTaskObjects = @("multicastsession", "scheduledtask", "snapinjob", "snapintask", "task"); } process { switch ($paramName) { coreObject { $attributeCollection.Add((New-Object ValidateSet($coreObjects)));} coreTaskObject {$attributeCollection.Add((New-Object ValidateSet($coreTaskObjects)));} coreActiveTaskObject {$attributeCollection.Add((New-Object ValidateSet($coreActiveTaskObjects)));} } $dynParam = New-Object System.Management.Automation.RuntimeDefinedParameter($paramName, [string], $attributeCollection); # $paramDictionary.Add($paramName, $dynParam); } end { return $dynParam; } } function Set-DynamicParams { <# .SYNOPSIS Sets the dynamic param dictionary .DESCRIPTION Sets dynamic parameters inside functions .PARAMETER type the type of parameter #> [CmdletBinding()] param ($type) $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary; # Sub function for setting function Set-Param($paramName) { $param = Get-DynmicParam -paramName $paramName; $paramDictionary.Add($paramName, $param); } switch ($type) { object { Set-Param('coreObject');} objectactivetasktype { Set-Param('coreActiveTaskObject');} objecttasktype {Set-Param('coreTaskObject');} search {Set-Param('stringToSearch');} } return $paramDictionary; } |