Gathers a list of ADComputer objects

        :param str base_dn: The base DN to search within
        :param list samaccountnames: A list of computer names for which objects will be
            created, defaults to all computers if unspecified
        :param list attributes: Object attributes to populate, defaults to all

        :return: A list of populated ADComputer objects
        :rtype: list

def computers(self, base_dn, samaccountnames=(), attributes=()):
        """Gathers a list of ADComputer objects

        :param str base_dn: The base DN to search within
        :param list samaccountnames: A list of computer names for which objects will be
            created, defaults to all computers if unspecified
        :param list attributes: Object attributes to populate, defaults to all

        :return: A list of populated ADComputer objects
        :rtype: list
        """
        ad_computers = []

        search_filter = '(&(objectClass=computer){0})'
        # If no samaccountnames specified, filter will pull all computer objects under
        # base_dn
        if not samaccountnames:
            search_filter = search_filter.format('(sAMAccountName=*)')
        else:
            if len(samaccountnames) == 1:
                computer_names = '(sAMAccountName={0})'.format(samaccountnames[0])
            else:
                computer_names = '(|{0})'.format(''.join(['(sAMAccountName={0})'.\
                                                          format(computer) for computer
                                                          in samaccountnames]))

            search_filter = search_filter.format(computer_names)


        logging.debug('%s Search filter: %s', self.__class__.__name__, search_filter)

        results = self.adq.search(base_dn, search_filter, attributes)

        for search_result in results:
            adc = self._object_factory(search_result)
            ad_computers.append(adc)

        return ad_computers