# These two functions are convenient for CRM admins to quickly gather a hosted organization object from on-premise Microsoft Dynamics.
# One function is to attempt to query the App server for a specific name.
# If no such records exist, then the second function would invoke to allow the user to select from a list of known Orgs.

$orgName='TestOrg'

function selectOrg {
    function pickList($list){
    # Although it's more efficient to obtain the index and set it as display,
    # humans prefer see a list that starts with 1, instead of 0
    $display=for ($i=0;$i -lt $list.count;$i++){
        "$($i+1)`:`t$($list[$i])`r`n";
        }
    $lines=($display | Measure-Object -Line).Lines
    write-host $($display)
    $maxAttempts=3
    $attempts=0;
    while ($attempts -le $maxAttempts){
        if($attempts++ -ge $maxAttempts){
            write-host "Attempt number $maxAttempts of $maxAttempts. Exiting loop..`r`n"
            break;
            }
        $userInput = Read-Host -Prompt 'Please pick a number from the list above';
        try {
            $value=[int]$userInput;
            }catch{
                $value=-1;
                }
        if ($value -lt 1 -OR $value -gt $lines){
            cls;
            write-host "Attempt number $attempts of $maxAttempts`: $userInput is an invalid value. Try again..`r`n"
            write-host $display
            }else{
                $item=$list[$value-1];
                write-host "$userInput corresponds to $item`r`n";
                return $item
                }
        }     
    }
    # Set Org name and database name - run this prior to pasting the rest of the lines below
    if(!(get-command get-crmorganization -ea SilentlyContinue)){Add-PSSnapin Microsoft.Crm.PowerShell}
    $orgs=Get-CrmOrganization|?{$_.State -ne 'Disabled'}
    try{$orgsValue=$orgs.gettype().Name}
    catch{write-warning "No Orgs detected on $env:computername. Exiting Program"; break;}
    if ($orgsValue -ne 'Organization'){
        $orgNames=$orgs.UniqueName|sort
        $orgName=$(pickList $orgNames)
        }
    else{$orgName=$orgs.UniqueName}
    $pickedOrg=$orgs|?{$_.UniqueName -eq $orgName}
    $orgFriendlyName=$pickedOrg.FriendlyName
    $orgId=$pickedOrg.Id
    $orgSqlServer=$pickedOrg.SqlServerName
    $orgDatabaseName=$pickedOrg.DatabaseName
    $orgSrsUrl=$pickedOrg.SrsUrl
    return @{
        'orgName'=$orgName
        'friendlyName'=$orgFriendlyName
        'sqlServer'=$orgSqlServer
        'databaseName'=$orgDatabaseName
        'srsUrl'=$orgSrsUrl
        'orgId'=$orgId
        }
}

function getOrg ($orgName){    
    if(!(get-command get-crmorganization -ea SilentlyContinue)){Add-PSSnapin Microsoft.Crm.PowerShell}
    $org=Get-CrmOrganization|?{$_.UniqueName -eq $orgName}
    if(!$org){
        write-warning "$orgName not found. Please try selecting from this list."
        return selectOrg
    }else{
        $orgFriendlyName=$org.FriendlyName
        $orgId=$org.Id
        $orgSqlServer=$org.SqlServerName
        $orgDatabaseName=$org.DatabaseName
        $orgSrsUrl=$org.SrsUrl
        return @{
            'orgName'=$orgName
            'friendlyName'=$orgFriendlyName
            'sqlServer'=$orgSqlServer
            'databaseName'=$orgDatabaseName
            'srsUrl'=$orgSrsUrl
            'orgId'=$orgId
            }
    }
}

getOrg $orgName